spine-framework 0.4.3 → 0.5.0-rc.4

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 (320) hide show
  1. package/.env.example +13 -3
  2. package/.framework/cli/commands/bootstrap.ts +392 -0
  3. package/.framework/cli/commands/dev.ts +91 -218
  4. package/.framework/cli/commands/doctor.ts +132 -26
  5. package/.framework/cli/commands/generate.ts +38 -298
  6. package/.framework/cli/commands/init.ts +20 -1
  7. package/.framework/cli/commands/migrate.ts +36 -30
  8. package/.framework/cli/commands/migrations.ts +16 -56
  9. package/.framework/cli/commands/upgrade.ts +35 -0
  10. package/.framework/cli/commands/validate-schema.ts +147 -0
  11. package/.framework/cli/context.ts +223 -110
  12. package/.framework/cli/index.ts +6 -0
  13. package/.framework/cli/lib/project-files.ts +241 -1
  14. package/.framework/functions/_shared/agent-runner.ts +1000 -81
  15. package/.framework/functions/_shared/cil.ts +2 -1
  16. package/.framework/functions/_shared/db.ts +3 -6
  17. package/.framework/functions/_shared/hash-api-key.ts +183 -79
  18. package/.framework/functions/_shared/kb.ts +61 -7
  19. package/.framework/functions/_shared/logging.ts +562 -224
  20. package/.framework/functions/_shared/message-sequence.ts +53 -0
  21. package/.framework/functions/_shared/middleware.ts +47 -44
  22. package/.framework/functions/_shared/pipeline-runner.ts +150 -37
  23. package/.framework/functions/_shared/principal.ts +9 -6
  24. package/.framework/functions/_shared/trigger-engine.ts +149 -40
  25. package/.framework/functions/admin-data.ts +48 -31
  26. package/.framework/functions/ai-agents.ts +103 -33
  27. package/.framework/functions/api-keys.ts +301 -122
  28. package/.framework/functions/apps.ts +43 -26
  29. package/.framework/functions/cil-ingest.ts +48 -15
  30. package/.framework/functions/debug-auth.ts +14 -8
  31. package/.framework/functions/deliveries.ts +39 -12
  32. package/.framework/functions/embeddings.ts +145 -76
  33. package/.framework/functions/integration-outbound.ts +67 -27
  34. package/.framework/functions/integrations.ts +254 -127
  35. package/.framework/functions/logs.ts +273 -133
  36. package/.framework/functions/observability.ts +277 -147
  37. package/.framework/functions/pipeline-executions.ts +1 -1
  38. package/.framework/functions/pipeline-runner-background.ts +120 -0
  39. package/.framework/functions/pipelines.ts +14 -9
  40. package/.framework/functions/prompt-configs.ts +7 -4
  41. package/.framework/functions/roles.ts +8 -5
  42. package/.framework/functions/security.ts +30 -17
  43. package/.framework/functions/system-cron.ts +250 -128
  44. package/.framework/functions/tests.ts +7 -6
  45. package/.framework/functions/timers.ts +310 -107
  46. package/.framework/functions/trigger-scheduler.ts +65 -5
  47. package/.framework/functions/triggers.ts +28 -13
  48. package/.framework/functions/types.ts +13 -10
  49. package/.framework/migrations/064_episode_leases.sql +196 -0
  50. package/.framework/migrations/065_execution_tables_updated_at.sql +20 -0
  51. package/.framework/migrations/066_episode_steal_thread_merge.sql +148 -0
  52. package/.framework/migrations/067_episode_lease_stale_steal.sql +93 -0
  53. package/.framework/migrations/068_cron_schedule_timer_rpcs.sql +251 -0
  54. package/.framework/migrations/069_log_stats_window.sql +54 -0
  55. package/.framework/migrations/070_app_type_schema_rpcs.sql +166 -0
  56. package/.framework/migrations/071_timer_interval_keys.sql +96 -0
  57. package/.framework/migrations/072_slug_autofill.sql +77 -0
  58. package/.framework/migrations/073_seed_member_roles.sql +26 -0
  59. package/.framework/schemas/spine.config.schema.json +62 -0
  60. package/.framework/src/App.tsx +3 -1
  61. package/.framework/src/apps/admin/index.tsx +1141 -775
  62. package/.framework/src/components/ErrorBoundary.tsx +136 -0
  63. package/.framework/src/components/admin/AdminListPage.tsx +81 -73
  64. package/.framework/src/components/admin/AdminSidebar.tsx +92 -81
  65. package/.framework/src/components/admin/EntitySelect.tsx +181 -0
  66. package/.framework/src/components/admin/PageInstructions.tsx +86 -127
  67. package/.framework/src/components/app-shell/GenericAppShell.tsx +3 -1
  68. package/.framework/src/components/app-shell/GenericDetailPage.tsx +37 -13
  69. package/.framework/src/components/app-shell/GenericListPage.tsx +28 -32
  70. package/.framework/src/components/auth/TurnstileWidget.tsx +9 -6
  71. package/.framework/src/components/kb/KBArticleEditor.tsx +49 -6
  72. package/.framework/src/components/layout/Layout.tsx +4 -2
  73. package/.framework/src/components/layout/Sidebar.tsx +304 -179
  74. package/.framework/src/components/runtime/DataDetailPage.tsx +67 -35
  75. package/.framework/src/components/runtime/DataHeader.tsx +96 -48
  76. package/.framework/src/components/runtime/DataListPage.tsx +3 -26
  77. package/.framework/src/components/runtime/DataStats.tsx +10 -10
  78. package/.framework/src/components/runtime/DataTable.tsx +12 -10
  79. package/.framework/src/components/ui/sheet.tsx +24 -26
  80. package/.framework/src/components/ui/textarea.tsx +74 -48
  81. package/.framework/src/hooks/useBranding.ts +47 -0
  82. package/.framework/src/hooks/useEntityList.ts +12 -9
  83. package/.framework/src/hooks/useListSchema.ts +108 -58
  84. package/.framework/src/instructions/README.md +57 -0
  85. package/.framework/src/instructions/ai-agents.md +69 -0
  86. package/.framework/src/instructions/alerts.md +80 -0
  87. package/.framework/src/instructions/api-keys.md +87 -0
  88. package/.framework/src/instructions/apps.md +77 -0
  89. package/.framework/src/instructions/concepts/ai-and-prompts.md +150 -0
  90. package/.framework/src/instructions/concepts/apps-and-renderers.md +162 -0
  91. package/.framework/src/instructions/concepts/auth-and-api-keys.md +133 -0
  92. package/.framework/src/instructions/concepts/automation.md +186 -0
  93. package/.framework/src/instructions/concepts/concurrency-and-idempotency.md +125 -0
  94. package/.framework/src/instructions/concepts/core-vs-custom.md +124 -0
  95. package/.framework/src/instructions/concepts/design-schema.md +152 -0
  96. package/.framework/src/instructions/concepts/integrations-and-webhooks.md +127 -0
  97. package/.framework/src/instructions/concepts/observability.md +116 -0
  98. package/.framework/src/instructions/concepts/permissions.md +150 -0
  99. package/.framework/src/instructions/concepts/runtime-records.md +111 -0
  100. package/.framework/src/instructions/concepts/scope-and-accounts.md +112 -0
  101. package/.framework/src/instructions/concepts/spine-way.md +172 -0
  102. package/.framework/src/instructions/deliveries.md +59 -0
  103. package/.framework/src/instructions/guide/00-orientation.md +106 -0
  104. package/.framework/src/instructions/guide/01-install-and-first-run.md +253 -0
  105. package/.framework/src/instructions/guide/02-project-map.md +147 -0
  106. package/.framework/src/instructions/guide/03-domain-model.md +223 -0
  107. package/.framework/src/instructions/guide/04-first-app.md +227 -0
  108. package/.framework/src/instructions/guide/05-glossary.md +183 -0
  109. package/.framework/src/instructions/integrations.md +96 -0
  110. package/.framework/src/instructions/internal/cil-markers.md +83 -0
  111. package/.framework/src/instructions/invites.md +60 -0
  112. package/.framework/src/instructions/kb.md +80 -0
  113. package/.framework/src/instructions/logs.md +77 -0
  114. package/.framework/src/instructions/observability.md +61 -0
  115. package/.framework/src/instructions/operations/deployment.md +115 -0
  116. package/.framework/src/instructions/operations/migrations.md +125 -0
  117. package/.framework/src/instructions/operations/security-checklist.md +148 -0
  118. package/.framework/src/instructions/operations/troubleshooting.md +170 -0
  119. package/.framework/src/instructions/operations/upgrade.md +116 -0
  120. package/.framework/src/instructions/pipeline-executions.md +62 -0
  121. package/.framework/src/instructions/pipelines.md +78 -0
  122. package/.framework/src/instructions/prompts.md +95 -0
  123. package/.framework/src/instructions/reference/api/admin-data.md +162 -0
  124. package/.framework/src/instructions/reference/api/auth.md +113 -0
  125. package/.framework/src/instructions/reference/api/errors-and-envelopes.md +113 -0
  126. package/.framework/src/instructions/reference/app-manifest.md +150 -0
  127. package/.framework/src/instructions/reference/cli.md +124 -0
  128. package/.framework/src/instructions/reference/database.md +132 -0
  129. package/.framework/src/instructions/reference/design-schema.md +280 -0
  130. package/.framework/src/instructions/reference/env-vars.md +133 -0
  131. package/.framework/src/instructions/reference/functions/account-nodes.md +75 -0
  132. package/.framework/src/instructions/reference/functions/admin-data.md +195 -0
  133. package/.framework/src/instructions/reference/functions/admin-funnel.md +90 -0
  134. package/.framework/src/instructions/reference/functions/admin-install-funnel.md +107 -0
  135. package/.framework/src/instructions/reference/functions/admin-signals.md +102 -0
  136. package/.framework/src/instructions/reference/functions/ai-agents.md +148 -0
  137. package/.framework/src/instructions/reference/functions/ai-interactions.md +156 -0
  138. package/.framework/src/instructions/reference/functions/api-keys.md +130 -0
  139. package/.framework/src/instructions/reference/functions/apps.md +140 -0
  140. package/.framework/src/instructions/reference/functions/auth.md +99 -0
  141. package/.framework/src/instructions/reference/functions/debug-auth.md +91 -0
  142. package/.framework/src/instructions/reference/functions/deliveries.md +110 -0
  143. package/.framework/src/instructions/reference/functions/embeddings.md +166 -0
  144. package/.framework/src/instructions/reference/functions/eval-harness.md +149 -0
  145. package/.framework/src/instructions/reference/functions/index.md +103 -0
  146. package/.framework/src/instructions/reference/functions/integration-outbound.md +200 -0
  147. package/.framework/src/instructions/reference/functions/integration-routes.md +151 -0
  148. package/.framework/src/instructions/reference/functions/integrations.md +130 -0
  149. package/.framework/src/instructions/reference/functions/invites.md +182 -0
  150. package/.framework/src/instructions/reference/functions/item-progress.md +107 -0
  151. package/.framework/src/instructions/reference/functions/kb.md +166 -0
  152. package/.framework/src/instructions/reference/functions/logs.md +141 -0
  153. package/.framework/src/instructions/reference/functions/observability.md +105 -0
  154. package/.framework/src/instructions/reference/functions/pipeline-executions.md +132 -0
  155. package/.framework/src/instructions/reference/functions/pipeline-runner-background.md +121 -0
  156. package/.framework/src/instructions/reference/functions/pipelines.md +136 -0
  157. package/.framework/src/instructions/reference/functions/prompt-configs.md +121 -0
  158. package/.framework/src/instructions/reference/functions/roles.md +121 -0
  159. package/.framework/src/instructions/reference/functions/security.md +140 -0
  160. package/.framework/src/instructions/reference/functions/system-cron.md +136 -0
  161. package/.framework/src/instructions/reference/functions/system.md +106 -0
  162. package/.framework/src/instructions/reference/functions/tests.md +97 -0
  163. package/.framework/src/instructions/reference/functions/timers.md +117 -0
  164. package/.framework/src/instructions/reference/functions/trigger-scheduler.md +102 -0
  165. package/.framework/src/instructions/reference/functions/triggers.md +140 -0
  166. package/.framework/src/instructions/reference/functions/types.md +146 -0
  167. package/.framework/src/instructions/reference/seeds.md +126 -0
  168. package/.framework/src/instructions/reference/shared-modules.md +127 -0
  169. package/.framework/src/instructions/reference/spine-config.md +114 -0
  170. package/.framework/src/instructions/roles.md +80 -0
  171. package/.framework/src/instructions/runtime-detail.md +70 -0
  172. package/.framework/src/instructions/runtime-list.md +77 -0
  173. package/.framework/src/instructions/security.md +67 -0
  174. package/.framework/src/instructions/tasks/add-a-pipeline.md +110 -0
  175. package/.framework/src/instructions/tasks/add-a-role.md +96 -0
  176. package/.framework/src/instructions/tasks/add-a-timer.md +114 -0
  177. package/.framework/src/instructions/tasks/add-a-trigger.md +106 -0
  178. package/.framework/src/instructions/tasks/add-a-type.md +151 -0
  179. package/.framework/src/instructions/tasks/add-a-webhook.md +108 -0
  180. package/.framework/src/instructions/tasks/add-an-ai-agent.md +108 -0
  181. package/.framework/src/instructions/tasks/add-an-integration.md +124 -0
  182. package/.framework/src/instructions/tasks/build-a-custom-page.md +118 -0
  183. package/.framework/src/instructions/tasks/package-and-install-an-app.md +127 -0
  184. package/.framework/src/instructions/tasks/test-your-code.md +108 -0
  185. package/.framework/src/instructions/tasks/write-a-function.md +132 -0
  186. package/.framework/src/instructions/tasks/write-a-migration.md +110 -0
  187. package/.framework/src/instructions/testing.md +59 -0
  188. package/.framework/src/instructions/timers.md +82 -0
  189. package/.framework/src/instructions/triggers.md +69 -0
  190. package/.framework/src/instructions/types.md +93 -0
  191. package/.framework/src/lib/branding.ts +128 -0
  192. package/.framework/src/pages/NoAppPage.tsx +3 -1
  193. package/.framework/src/pages/NotFoundPage.tsx +62 -31
  194. package/.framework/src/pages/SetupPage.tsx +5 -2
  195. package/.framework/src/pages/admin/AIAgentDetailPage.tsx +117 -106
  196. package/.framework/src/pages/admin/AIAgentsPage.tsx +86 -48
  197. package/.framework/src/pages/admin/APIKeyDetailPage.tsx +153 -152
  198. package/.framework/src/pages/admin/APIKeysPage.tsx +91 -90
  199. package/.framework/src/pages/admin/AlertsConfigPage.tsx +29 -18
  200. package/.framework/src/pages/admin/AppDetailPage.tsx +6 -60
  201. package/.framework/src/pages/admin/AppsPage.tsx +104 -66
  202. package/.framework/src/pages/admin/DeliveriesPage.tsx +5 -5
  203. package/.framework/src/pages/admin/EmbeddingDetailPage.tsx +5 -23
  204. package/.framework/src/pages/admin/EmbeddingsPage.tsx +5 -26
  205. package/.framework/src/pages/admin/IntegrationDetailPage.tsx +7 -7
  206. package/.framework/src/pages/admin/IntegrationsPage.tsx +85 -43
  207. package/.framework/src/pages/admin/LogsPage.tsx +144 -76
  208. package/.framework/src/pages/admin/ObservabilityDashboard.tsx +223 -140
  209. package/.framework/src/pages/admin/PipelineDetailPage.tsx +134 -113
  210. package/.framework/src/pages/admin/PipelineExecutionsPage.tsx +108 -45
  211. package/.framework/src/pages/admin/PipelinesPage.tsx +160 -115
  212. package/.framework/src/pages/admin/PromptConfigDetailPage.tsx +96 -98
  213. package/.framework/src/pages/admin/PromptConfigsPage.tsx +101 -59
  214. package/.framework/src/pages/admin/RoleDetailPage.tsx +90 -79
  215. package/.framework/src/pages/admin/RolesPage.tsx +86 -43
  216. package/.framework/src/pages/admin/SecurityPage.tsx +1 -1
  217. package/.framework/src/pages/admin/TestingDashboard.tsx +16 -28
  218. package/.framework/src/pages/admin/TimerDetailPage.tsx +117 -100
  219. package/.framework/src/pages/admin/TimersPage.tsx +90 -62
  220. package/.framework/src/pages/admin/TriggerDetailPage.tsx +90 -83
  221. package/.framework/src/pages/admin/TriggersPage.tsx +124 -99
  222. package/.framework/src/pages/admin/TypeDetailPage.tsx +152 -138
  223. package/.framework/src/pages/admin/TypesPage.tsx +90 -48
  224. package/.framework/src/pages/admin/cil/CILAgentPage.tsx +17 -25
  225. package/.framework/src/pages/admin/cil/CILChunkDetailPage.tsx +17 -27
  226. package/.framework/src/pages/admin/cil/CILDashboardPage.tsx +72 -40
  227. package/.framework/src/pages/admin/cil/CILFileListPage.tsx +321 -129
  228. package/.framework/src/pages/admin/cil/CILFileSelectPage.tsx +18 -29
  229. package/.framework/src/pages/admin/cil/CILGraphPage.tsx +26 -38
  230. package/.framework/src/pages/admin/cil/CILIngestionPage.tsx +34 -46
  231. package/.framework/src/pages/admin/cil/CILProjectsPage.tsx +189 -103
  232. package/.framework/src/pages/admin/cil/CILSearchPage.tsx +246 -136
  233. package/.framework/src/pages/admin/cil/CILSuggestionsPage.tsx +11 -22
  234. package/.framework/src/pages/admin/cil/CILVersionsPage.tsx +9 -20
  235. package/.framework/src/pages/admin/cil/FlexiblePipelinePage.tsx +26 -38
  236. package/.framework/src/pages/admin/kb/KBAdminPage.tsx +7 -26
  237. package/.framework/src/pages/auth/AuthConfirmPage.tsx +3 -1
  238. package/.framework/src/pages/auth/ForgotPasswordPage.tsx +3 -1
  239. package/.framework/src/pages/auth/LoginPage.tsx +4 -2
  240. package/.framework/src/pages/auth/RegisterPage.tsx +3 -1
  241. package/.framework/templates/agent/AGENTS.md +150 -0
  242. package/.framework/templates/agent/skills/spine-add-ai-agent/SKILL.md +58 -0
  243. package/.framework/templates/agent/skills/spine-add-automation/SKILL.md +62 -0
  244. package/.framework/templates/agent/skills/spine-add-integration/SKILL.md +63 -0
  245. package/.framework/templates/agent/skills/spine-architect/SKILL.md +86 -0
  246. package/.framework/templates/agent/skills/spine-install-app/SKILL.md +72 -0
  247. package/.framework/templates/agent/skills/spine-migration/SKILL.md +75 -0
  248. package/.framework/templates/agent/skills/spine-new-app/SKILL.md +67 -0
  249. package/.framework/templates/agent/skills/spine-new-function/SKILL.md +65 -0
  250. package/.framework/templates/agent/skills/spine-new-type/SKILL.md +65 -0
  251. package/.framework/templates/agent/skills/spine-schema/SKILL.md +77 -0
  252. package/.framework/templates/agent/skills/spine-test/SKILL.md +67 -0
  253. package/.framework/templates/agent/skills/spine-troubleshoot/SKILL.md +74 -0
  254. package/.framework/templates/agent/skills/spine-upgrade/SKILL.md +69 -0
  255. package/.framework/templates/project.json +5 -1
  256. package/.framework/tests/unit/account-scoping-gates.test.ts +392 -0
  257. package/.framework/tests/unit/agent-files.test.ts +355 -0
  258. package/.framework/tests/unit/agent-runner.test.ts +496 -47
  259. package/.framework/tests/unit/api-keys-create-scope-gate.test.ts +160 -0
  260. package/.framework/tests/unit/api-keys-omit-secret-fields.test.ts +38 -0
  261. package/.framework/tests/unit/bootstrap.test.ts +242 -0
  262. package/.framework/tests/unit/cli-context-api-key.test.ts +114 -0
  263. package/.framework/tests/unit/debug-auth.test.ts +38 -0
  264. package/.framework/tests/unit/deliveries-account-scoping.test.ts +185 -0
  265. package/.framework/tests/unit/episode-lease.test.ts +695 -0
  266. package/.framework/tests/unit/integration-outbound-credentials.test.ts +167 -0
  267. package/.framework/tests/unit/integrations-audit-redaction.test.ts +130 -0
  268. package/.framework/tests/unit/kb-ingest-lease.test.ts +19 -0
  269. package/.framework/tests/unit/logging-app-id.test.ts +75 -0
  270. package/.framework/tests/unit/pipeline-runner-background.test.ts +120 -0
  271. package/.framework/tests/unit/pipeline-runner.test.ts +153 -1
  272. package/.framework/tests/unit/principal-cache.test.ts +15 -0
  273. package/.framework/tests/unit/system-context-denial.test.ts +145 -0
  274. package/.framework/tests/unit/system-cron.test.ts +240 -0
  275. package/.framework/tests/unit/timers.test.ts +159 -0
  276. package/.framework/tests/unit/trigger-engine.test.ts +278 -91
  277. package/.framework/tests/unit/trigger-scheduler.test.ts +78 -0
  278. package/README.md +125 -166
  279. package/config/tsconfig.cli.json +2 -2
  280. package/netlify.toml +5 -0
  281. package/package.json +15 -4
  282. package/templates/project/package-lock.json +2 -2
  283. package/.framework/docs/admin-routes.md +0 -76
  284. package/.framework/docs/api-docs-progress.md +0 -38
  285. package/.framework/docs/api-governance.md +0 -146
  286. package/.framework/docs/api-testing-results.md +0 -212
  287. package/.framework/docs/assembly-launch-guide.md +0 -138
  288. package/.framework/docs/audit-results.md +0 -590
  289. package/.framework/docs/db-api-inventory.md +0 -95
  290. package/.framework/docs/gap-remediation-backlog.md +0 -103
  291. package/.framework/docs/ui-adoption-verification.md +0 -111
  292. package/.framework/docs/ui-api-coverage.md +0 -84
  293. package/.framework/docs/v2-compatibility-audit.md +0 -228
  294. package/.framework/mcp/index.ts +0 -133
  295. package/.framework/mcp/load-env.ts +0 -60
  296. package/.framework/mcp/shared/app-manifest.ts +0 -275
  297. package/.framework/mcp/shared/db.ts +0 -477
  298. package/.framework/mcp/shared/kb.ts +0 -118
  299. package/.framework/mcp/tools/architect.ts +0 -431
  300. package/.framework/mcp/tools/cil/context.ts +0 -345
  301. package/.framework/mcp/tools/cil/graph.ts +0 -242
  302. package/.framework/mcp/tools/cil/ingest.ts +0 -1217
  303. package/.framework/mcp/tools/cil/pipeline-orchestrator.ts +0 -693
  304. package/.framework/mcp/tools/cil/pipeline.ts +0 -767
  305. package/.framework/mcp/tools/cil/project.ts +0 -791
  306. package/.framework/mcp/tools/cil/retrieval.ts +0 -336
  307. package/.framework/mcp/tools/cil/search-core.ts +0 -454
  308. package/.framework/mcp/tools/cil/search.ts +0 -97
  309. package/.framework/mcp/tools/cil/suggest.ts +0 -186
  310. package/.framework/mcp/tools/cil/validate.ts +0 -1369
  311. package/.framework/mcp/tools/kb/delete.ts +0 -139
  312. package/.framework/mcp/tools/kb/index.ts +0 -52
  313. package/.framework/mcp/tools/kb/ingest.ts +0 -84
  314. package/.framework/mcp/tools/kb/list-types.ts +0 -102
  315. package/.framework/mcp/tools/kb/publish.ts +0 -100
  316. package/.framework/mcp/tools/kb/reindex.ts +0 -86
  317. package/.framework/mcp/tools/kb/revoke.ts +0 -85
  318. package/.framework/mcp/tools/kb/search.ts +0 -101
  319. package/.framework/mcp/tools/kb/upsert.ts +0 -125
  320. package/.framework/mcp/tools/observability.ts +0 -510
@@ -0,0 +1,223 @@
1
+ ---
2
+ title: The Spine domain model
3
+ audience: developers, agents
4
+ kind: guide
5
+ verified_against: f69c37d
6
+ verified_on: 2026-10-29
7
+ source_files:
8
+ - .framework/migrations/001_core_schema.sql
9
+ - .framework/migrations/003_core_system_data.sql
10
+ - .framework/migrations/004_core_rpc_and_broker.sql
11
+ - .framework/migrations/020_schema_reconciliation.sql
12
+ - .framework/functions/admin-data.ts
13
+ - .framework/functions/_shared/permissions.ts
14
+ - .framework/functions/_shared/principal.ts
15
+ - .framework/functions/_shared/trigger-engine.ts
16
+ - .framework/functions/_shared/pipeline-runner.ts
17
+ - .framework/functions/system-cron.ts
18
+ - .framework/functions/trigger-scheduler.ts
19
+ - .framework/functions/pipeline-runner-background.ts
20
+ - .framework/src/App.tsx
21
+ - .framework/src/components/app-shell/GenericAppShell.tsx
22
+ - .framework/src/components/CustomAppLoader.tsx
23
+ - .framework/src/contexts/AppContext.tsx
24
+ - .framework/src/hooks/useApps.ts
25
+ - netlify.toml
26
+ ---
27
+
28
+ # The Spine domain model
29
+
30
+ Everything in Spine is one of about ten primitives. Once you can name them and
31
+ say how they connect, the whole system — admin UI, APIs, automation — is just
32
+ compositions of the diagram below.
33
+
34
+ ```
35
+ ┌──────────────────────── IDENTITY ────────────────────────┐
36
+ │ │
37
+ auth.users (Supabase) │ account ──< people >── role │
38
+ │ │ (tenant, (human, (permission │
39
+ │ auth_uid │ tree via auth_uid, set; system_admin │
40
+ ▼ │ parent_id account_id, is the seeded root) │
41
+ JWT / x-api-key ──────┤ + account_ role_id) │
42
+ │ │ paths) │
43
+ ▼ └──────────────────────────┬─────────────────────────────┘
44
+ principal ─────────── every request resolves one │
45
+ (anonymous | human | machine | system) │
46
+ ▼
47
+ ┌──────────────────────── SCHEMA ─────────────────────────┐
48
+ │ type (kind + slug) → design_schema → validation_schema │
49
+ │ fields · views · record_permissions · scope │
50
+ └──────────────────────────┬─────────────────────────────┘
51
+ │ stamped at create
52
+ ▼
53
+ ┌──────────────────────── RECORDS ────────────────────────┐
54
+ │ items · threads · messages · links · attachments · │
55
+ │ watchers (+ accounts, people as records) │
56
+ │ system columns + data jsonb + stamped schemas │
57
+ └──────────────────────────┬─────────────────────────────┘
58
+ │ CRUD via /api/admin-data
59
+ ┌──────────────────────── APPS ◄────────────┘ renders / consumes
60
+ │ generic | custom | none │
61
+ │ app row: slug, route_prefix, renderer, ▼
62
+ │ nav_items, roles ┌────────────────────── AUTOMATION ───────┐
63
+ └───────────────┬────────────────┤ triggers (event) → pipelines (stages) │
64
+ │ seeds/owns │ timers (cron/interval/once) ──┘ │
65
+ ▼ │ integrations (adapters+creds) │
66
+ ┌──────────────────────── AI ────┤ ai_agents · prompt_configs · │
67
+ │ embeddings (pgvector search) │ embeddings │
68
+ └────────────────────────────────┴──────────────┬────────────────────────┘
69
+ ▼
70
+ ┌──────────────────────── OBSERVE ────────────────────────┐
71
+ │ logs · observability · pipeline_executions · │
72
+ │ trigger_executions · webhook_deliveries · │
73
+ │ api_key_usage_logs · audit │
74
+ └─────────────────────────────────────────────────────────┘
75
+ ```
76
+
77
+ ## Identity: account → person → role → principal
78
+
79
+ - **Account** (`public.accounts`) — the tenant. Accounts form a hierarchy via
80
+ `parent_id` + the `account_paths` closure table; the seeded `spine-system`
81
+ account is the platform root
82
+ (`.framework/migrations/011_spine_system_account.sql`).
83
+ - **Person** (`public.people`) — a human user, bound to `auth.users` by
84
+ `auth_uid`, placed in one `account_id`, holding one `role_id`. Like every
85
+ runtime record, a person row also carries `type_id` and `data`.
86
+ - **Role** (`public.roles`) — a named permission set with a globally unique
87
+ `slug`. `system_admin` is seeded, protected, and bypasses record-level
88
+ checks (`.framework/migrations/003_core_system_data.sql`).
89
+ - **Principal** — the *resolved* identity of a request, computed per call by
90
+ `.framework/functions/_shared/principal.ts`: `x-api-key` header → machine
91
+ principal (verified against `api_keys` hash), internal-invoke headers →
92
+ cron/trigger/system, `Authorization: Bearer` JWT → human principal, anything
93
+ else → anonymous. Handlers receive it as `ctx.principal` with
94
+ `ctx.accountId`.
95
+
96
+ ## Schema: type → design_schema → validation_schema
97
+
98
+ A **type** (`public.types`) is the schema for a record kind. `kind` selects the
99
+ runtime table — `item`, `thread`, `message`, `link`, `attachment`, `watcher`,
100
+ `account`, `person` — and `(kind, slug)` is unique. Its `design_schema` JSON
101
+ carries:
102
+
103
+ - `fields` — each with `data_type`, `label`, `required`, and optional
104
+ `system` flag.
105
+ - `views` — `default_list` / `default_detail` consumed by the generic UI.
106
+ - `record_permissions` — per-role base grant of `create`/`read`/`update`/
107
+ `delete`; `fields.*.permissions` exists only to *override* that base per
108
+ field (`.framework/functions/_shared/permissions.ts`).
109
+ - `scope` — `account` (tenant data, the default) or `platform` (record is
110
+ re-anchored to the `spine-system` account at create).
111
+
112
+ `validation_schema` is **generated from `design_schema`** on every save
113
+ (`.framework/functions/types.ts` via `_shared/schema-utils.ts`) — never
114
+ hand-edit it.
115
+
116
+ ## Records: the runtime tables
117
+
118
+ Six typed record tables — `items`, `threads`, `messages`, `links`,
119
+ `attachments`, `watchers` — plus `accounts` and `people` in the same shape
120
+ (`.framework/migrations/001_core_schema.sql`). Every record has:
121
+
122
+ - **system columns** — `id`, `type_id`, `account_id`, `app_id`, `created_at`,
123
+ `updated_at`, `created_by`, `is_active`, plus kind-specific ones
124
+ (`items.title/status`, `threads.target_type/target_id`,
125
+ `messages.thread_id/sequence`, `links.source_*/target_*`,
126
+ `attachments.storage_path`, `watchers.person_id`).
127
+ - **`data` jsonb** — where all non-system schema fields live. Convention:
128
+ `system: true` fields read from `record.<field>`; everything else from
129
+ `record.data.<field>` (see `GenericDetailPage` splitting on
130
+ `fieldDef.system` in `.framework/src/components/app-shell/GenericDetailPage.tsx`).
131
+ - **stamped `design_schema` + `validation_schema`** — copied from the type at
132
+ create time by `admin-data` (`create` in `.framework/functions/admin-data.ts`),
133
+ so the record is the source of truth for its own permissions even if the
134
+ type changes later.
135
+
136
+ All CRUD flows through `/api/admin-data` (`action=list|get|stats|create|
137
+ update|remove`, `entity=<table>`; GET for reads, POST/PATCH/DELETE for writes). The handler maps entity → kind
138
+ (`ENTITY_TO_KIND`), resolves `type_slug`/`type_id`, evaluates record/field
139
+ permissions, writes, then fires create/update/delete triggers.
140
+
141
+ ## Apps: registry + two renderers
142
+
143
+ An **app** (`public.apps`) is a registered application: `slug`,
144
+ `route_prefix`, `renderer`, `nav_items`, `min_role`/`required_roles`,
145
+ `config`, `is_active`, `is_system`. The authenticated router
146
+ (`.framework/src/App.tsx`) mounts every routable app at its `route_prefix`:
147
+
148
+ - **`renderer: 'generic'`** — `GenericAppShell` builds the UI *from data*: the
149
+ sidebar comes from `nav_items`, and each nav item with a `type_slug` gets
150
+ list/new/detail routes rendered by `GenericListPage`/`GenericDetailPage`
151
+ straight from the type's `views`
152
+ (`.framework/src/components/app-shell/GenericAppShell.tsx`).
153
+ - **`renderer: 'custom'`** — `CustomAppLoader` lazy-loads
154
+ `custom/apps/<slug>/index.tsx` (falling back to
155
+ `.framework/src/apps/<slug>/index.tsx`)
156
+ (`.framework/src/components/CustomAppLoader.tsx`). Custom apps render their
157
+ own pages but still use `/api/admin-data` for record CRUD.
158
+ - **`renderer: 'none'`** — registry-only; not routable.
159
+
160
+ ## Automation: triggers → pipelines, timers → pipelines
161
+
162
+ - **Pipeline** (`public.pipelines`) — a `stages` array executed in order by
163
+ `runPipeline` (`.framework/functions/_shared/pipeline-runner.ts`). Each
164
+ stage's `stage_type` resolves to a `public.actions` row or a built-in
165
+ handler (`update_item`, `create_record`, `http_request`,
166
+ `send_notification`, `send_email`, `run_pipeline`, `query_items`,
167
+ `agent_inference`, `search_knowledge`, `generate_embeddings`,
168
+ `revoke_embeddings`, `kb_ingest`, `kb_revoke`, `create_interaction`).
169
+ Every run writes a `pipeline_executions` row.
170
+ - **Trigger** (`public.triggers`) — `event_type` + `pipeline_id` (+ optional
171
+ `config` filters). `admin-data` calls `fireCreate/Update/DeleteTriggers`
172
+ after each write; events are named `<entity>_<created|updated|deleted>`
173
+ (e.g. `item_created`). A match enqueues a `pipeline_executions` row and
174
+ dispatches to the `pipeline-runner-background` function over HTTP — which
175
+ requires `INTERNAL_INVOKE_SECRET` to be set
176
+ (`.framework/functions/_shared/trigger-engine.ts`).
177
+ - **Timer** (`public.timers`) — `timer_type` (`interval` | `cron` | `once`) +
178
+ `pipeline_id` + schedule in `config`. The scheduled function
179
+ `trigger-scheduler` (every minute, `netlify.toml`) runs `system-cron`,
180
+ which calls the `get_due_timers` RPC and executes each due timer's pipeline
181
+ under a `timer:*` machine principal
182
+ (`.framework/functions/system-cron.ts`).
183
+
184
+ ## Integrations and AI
185
+
186
+ - **Integration** (`public.integrations`) — a named adapter + `config` +
187
+ `credentials` (`{"env_var": "NAME"}` resolved in the function environment,
188
+ or a literal `{"value": …}`). Inbound webhooks arrive via
189
+ `integration-routes`; outbound calls go through `integration-outbound`,
190
+ which records each attempt in `public.webhook_deliveries` (the deliveries
191
+ ledger — `system-cron` retries pending ones via
192
+ `.framework/functions/_shared/retry-deliveries.ts`).
193
+ - **AI agent** (`public.ai_agents`) — a model/prompt/tool config invocable via
194
+ `/api/ai-agents?action=run` or the `agent_inference` pipeline stage.
195
+ **Prompt config** (`public.prompt_configs`) — named, versioned prompt
196
+ templates agents and stages reference.
197
+ - **Embedding** (`public.embeddings`) — pgvector vectors with the
198
+ `match_embeddings` / `search_similar_embeddings` RPCs
199
+ (`.framework/migrations/004_core_rpc_and_broker.sql`), powering semantic
200
+ search and the `search_knowledge` stage type.
201
+
202
+ ## Observability: everything leaves a trail
203
+
204
+ `public.logs` (per-account log stream), `public.observability` (metrics),
205
+ `pipeline_executions` + `trigger_executions` (automation history),
206
+ `webhook_deliveries` (outbound attempts), `api_key_usage_logs` (machine
207
+ principal usage), and audit events emitted by `emitAudit` on privileged
208
+ actions. The admin UI surfaces them under Observability, Deliveries, and
209
+ Executions (`.framework/functions/logs.ts`,
210
+ `.framework/functions/observability.ts`,
211
+ `.framework/functions/pipeline-executions.ts`,
212
+ `.framework/functions/deliveries.ts`).
213
+
214
+ ## Where to go next
215
+
216
+ - Entity deep-dives: [types](../types.md), [apps](../apps.md),
217
+ [roles](../roles.md), [pipelines](../pipelines.md),
218
+ [triggers](../triggers.md), [timers](../timers.md),
219
+ [integrations](../integrations.md), [ai-agents](../ai-agents.md),
220
+ [prompts](../prompts.md), [api-keys](../api-keys.md),
221
+ [deliveries](../deliveries.md).
222
+ - Build something: [04-first-app.md](./04-first-app.md).
223
+ - Terminology: [05-glossary.md](./05-glossary.md).
@@ -0,0 +1,227 @@
1
+ ---
2
+ title: Build your first app
3
+ audience: developers, agents
4
+ kind: guide
5
+ verified_against: f69c37d
6
+ verified_on: 2026-10-29
7
+ source_files:
8
+ - .framework/functions/types.ts
9
+ - .framework/functions/apps.ts
10
+ - .framework/functions/admin-data.ts
11
+ - .framework/functions/_shared/trigger-engine.ts
12
+ - .framework/functions/_shared/schema-utils.ts
13
+ - .framework/src/components/app-shell/GenericAppShell.tsx
14
+ - .framework/src/components/app-shell/GenericListPage.tsx
15
+ - .framework/src/components/app-shell/GenericDetailPage.tsx
16
+ - .framework/src/components/CustomAppLoader.tsx
17
+ - .framework/src/contexts/AppContext.tsx
18
+ - .framework/src/lib/api.ts
19
+ - .framework/cli/commands/create-app.ts
20
+ - .framework/cli/commands/generate.ts
21
+ - .framework/cli/commands/install-app.ts
22
+ ---
23
+
24
+ # Build your first app
25
+
26
+ The smallest useful Spine app is one type + one app row — no code at all.
27
+ This walkthrough builds a `task` tracker end to end, then adds a custom page
28
+ and a pipeline. You need a `system_admin` login (see
29
+ [01-install-and-first-run.md](./01-install-and-first-run.md)) — app creation
30
+ is restricted to system admins (`.framework/functions/apps.ts`).
31
+
32
+ ## Step 1 — define the type
33
+
34
+ Admin UI → **Configs → Types → New** (or `POST /api/types`). Set:
35
+
36
+ - **Kind**: `item` — records land in `public.items`.
37
+ - **Slug**: `task` — unique within `kind`; callers resolve types by it.
38
+ - **Design schema** — the fields, views, and permissions below.
39
+
40
+ ```json
41
+ {
42
+ "scope": "account",
43
+ "fields": {
44
+ "title": { "data_type": "text", "label": "Title", "required": true, "system": true },
45
+ "status": { "data_type": "select", "label": "Status", "required": true,
46
+ "options": ["todo", "doing", "done"] },
47
+ "priority": { "data_type": "select", "label": "Priority", "required": false,
48
+ "options": ["low", "normal", "high"] },
49
+ "notes": { "data_type": "textarea", "label": "Notes", "required": false }
50
+ },
51
+ "views": {
52
+ "default_list": {
53
+ "type": "list", "display": "table", "label": "Tasks",
54
+ "fields": {
55
+ "title": { "sortable": true, "display_type": "text" },
56
+ "status": { "sortable": true, "display_type": "badge" },
57
+ "priority": { "sortable": true, "display_type": "badge" },
58
+ "created_at": { "sortable": true, "display_type": "timestamp" }
59
+ },
60
+ "default_sort": { "field": "created_at", "direction": "desc" }
61
+ },
62
+ "default_detail": {
63
+ "type": "detail", "label": "Task",
64
+ "sections": [
65
+ { "title": "Core",
66
+ "fields": {
67
+ "title": { "display_type": "input" },
68
+ "status": { "display_type": "select" },
69
+ "priority": { "display_type": "select" },
70
+ "notes": { "display_type": "textarea" }
71
+ } }
72
+ ]
73
+ }
74
+ },
75
+ "record_permissions": {
76
+ "system_admin": ["create", "read", "update", "delete"],
77
+ "engineering": ["create", "read", "update"]
78
+ },
79
+ "functionality": null
80
+ }
81
+ ```
82
+
83
+ On save, `validation_schema` is regenerated from `design_schema` by the types
84
+ API (`.framework/functions/types.ts`,
85
+ `.framework/functions/_shared/schema-utils.ts`) — you never write it yourself.
86
+ The rules that matter here: `select` fields need `options`; `title` is
87
+ `system: true` so it maps to the `items.title` column while `status`,
88
+ `priority`, and `notes` live in `items.data`; `record_permissions` is the base
89
+ grant evaluated on every `/api/admin-data` call, and its keys are matched
90
+ **verbatim** against `roles.slug` — so use real seeded slugs (`system_admin`,
91
+ `engineering`, `support`, …); a nonexistent or misspelled slug silently grants
92
+ nothing (`.framework/functions/_shared/permissions.ts`).
93
+
94
+ ## Step 2 — register the app
95
+
96
+ Admin UI → **Configs → Apps → New** (or `POST /api/apps`):
97
+
98
+ ```json
99
+ {
100
+ "slug": "taskboard",
101
+ "name": "Taskboard",
102
+ "route_prefix": "/taskboard",
103
+ "renderer": "generic",
104
+ "min_role": "engineering",
105
+ "is_active": true,
106
+ "nav_items": [
107
+ { "id": "tasks", "label": "Tasks", "path": "tasks", "type_slug": "task" }
108
+ ]
109
+ }
110
+ ```
111
+
112
+ `route_prefix` mounts the app at `/taskboard`; `renderer: "generic"` tells the
113
+ router to use `GenericAppShell`; each `nav_items` entry with a `type_slug`
114
+ gets list, `new`, and `:id` routes rendered from the type's views
115
+ (`.framework/src/components/app-shell/GenericAppShell.tsx`,
116
+ `GenericListPage.tsx`, `GenericDetailPage.tsx`). An app is routable when it
117
+ has a `route_prefix` and a renderer other than `none`
118
+ (`.framework/src/contexts/AppContext.tsx`).
119
+
120
+ Sign out/in (or wait for the apps registry refetch) and `/taskboard` renders
121
+ the Tasks list — create, edit, sort, and detail all work with zero code.
122
+
123
+ ## Step 3 — add custom UI
124
+
125
+ When the generic views are not enough, switch `renderer` to `custom` and put
126
+ your code where the loader looks for it:
127
+
128
+ ```bash
129
+ npx spine-framework create-app taskboard --role engineering
130
+ ```
131
+
132
+ This scaffolds `custom/apps/taskboard/` with `manifest.json`, `index.tsx`
133
+ (a React Router stub), and `components/`, and registers the `apps` row with
134
+ `renderer: 'custom'` (`.framework/cli/commands/create-app.ts` — if the row
135
+ already exists it skips the insert). `CustomAppLoader` lazy-loads
136
+ `custom/apps/taskboard/index.tsx` via `import.meta.glob`
137
+ (`.framework/src/components/CustomAppLoader.tsx`), so edit the component, then:
138
+
139
+ ```bash
140
+ npm run dev:netlify # assemble runs automatically; or: npm run assemble && netlify dev
141
+ ```
142
+
143
+ Your app is a normal React app under the `/taskboard/*` route, inside
144
+ `AppWrapper`. Custom functions go in `custom/functions/` (prefix filenames
145
+ `custom_` — assembly hard-fails on basename collisions with framework
146
+ functions; see [02-project-map.md](./02-project-map.md)).
147
+
148
+ ## Step 4 — CRUD via `/api/admin-data`
149
+
150
+ Custom pages use the same endpoint as the generic renderer — never write a
151
+ bespoke CRUD function:
152
+
153
+ ```ts
154
+ import { apiFetch } from '@core/lib/api' // assembled alias → .framework/src
155
+
156
+ // list
157
+ await apiFetch('/api/admin-data?action=list&entity=items&type_slug=task&limit=50')
158
+
159
+ // create — type_slug resolves the type; non-system fields go in `data`
160
+ await apiFetch('/api/admin-data?action=create', {
161
+ method: 'POST',
162
+ headers: { 'Content-Type': 'application/json' },
163
+ body: JSON.stringify({
164
+ entity: 'items',
165
+ type_slug: 'task',
166
+ title: 'Ship the docs',
167
+ data: { status: 'todo', priority: 'high' }
168
+ })
169
+ })
170
+
171
+ // update — entity + id are query params; the body is the field patch
172
+ await apiFetch('/api/admin-data?action=update&entity=items&id=<uuid>', {
173
+ method: 'PATCH',
174
+ headers: { 'Content-Type': 'application/json' },
175
+ body: JSON.stringify({ data: { status: 'doing' } })
176
+ })
177
+
178
+ // remove — soft-deletes (is_active = false) unless soft=false is passed
179
+ await apiFetch(`/api/admin-data?action=remove&entity=items&id=<uuid>`, { method: 'DELETE' })
180
+ ```
181
+
182
+ `apiFetch` (`.framework/src/lib/api.ts`) attaches the Supabase Bearer token and
183
+ the `X-Account-Id` header; `admin-data` resolves `task` → its `type_id`,
184
+ stamps `design_schema`/`validation_schema` onto the new record, evaluates
185
+ `record_permissions` for the caller's role, writes, and fires
186
+ `item_created` triggers (`.framework/functions/admin-data.ts`).
187
+
188
+ ## Step 5 — wire a pipeline
189
+
190
+ 1. Admin UI → **Configs → Pipelines → New**: name it, `trigger_type` =
191
+ `event`, `stages` = e.g. a `send_notification` stage
192
+ (`.framework/functions/_shared/pipeline-runner.ts` has the built-in
193
+ `stage_type` list).
194
+ 2. Admin UI → **Configs → Triggers → New**: `event_type` = `item_created`,
195
+ `pipeline_id` = the pipeline from step 1, `config.type_slug` = `task` to
196
+ scope it (`.framework/functions/_shared/trigger-engine.ts`).
197
+ 3. Ensure `INTERNAL_INVOKE_SECRET` is set — trigger dispatch POSTs to the
198
+ `pipeline-runner-background` function and silently no-ops without it.
199
+ 4. Create a task → the trigger queues a `pipeline_executions` row and the
200
+ background runner executes the stages; watch it under
201
+ **Observability → Executions**.
202
+
203
+ ## Gaps
204
+
205
+ - **`npx spine-framework generate` was removed.** The old scaffold wrote
206
+ stubs to a `v2-custom/` tree with `../v2-core/...` imports and a legacy
207
+ `design_schema` shape (`type`/`layout` instead of `data_type`/`views`). It
208
+ now prints migration guidance and exits 1
209
+ (`.framework/cli/commands/generate.ts`). Author types in the admin UI or via
210
+ `/api/types` instead.
211
+ - **`create-app` defaults `--role member`.** `member` and `member_admin`
212
+ are seeded by `.framework/migrations/073_seed_member_roles.sql` (003
213
+ seeds `system_admin`, `engineering`, `engineering_admin`, `product`,
214
+ `docs`, `qa`, `devops`, `management`, `sales`, `csm`, `tam`, `support`,
215
+ `support_admin`), so the default is valid on current installs. On a
216
+ database that predates 073, pass `--role` a slug that exists in your
217
+ `roles` table or create the role first.
218
+ - **`create-app` scaffold is minimal** — a `Routes` stub only. There is no
219
+ generated CRUD page, `admin-data` hook, or seed block in the manifest it
220
+ writes; the pattern in Step 4 is the integration contract.
221
+ - **Generic renderer is list/detail only.** `GenericAppShell` generates routes
222
+ solely for nav items carrying `type_slug`; a nav item without one renders a
223
+ sidebar button that navigates nowhere routable. Dashboards, wizards, or
224
+ bespoke layouts require `renderer: 'custom'`.
225
+ - **No packaged example app ships in the npm package** — `custom/` is created
226
+ empty by `init`, so there is no reference implementation to copy inside an
227
+ installed project.
@@ -0,0 +1,183 @@
1
+ ---
2
+ title: Glossary
3
+ audience: developers, agents
4
+ kind: guide
5
+ verified_against: f69c37d
6
+ verified_on: 2026-10-29
7
+ source_files:
8
+ - .framework/migrations/001_core_schema.sql
9
+ - .framework/migrations/004_core_rpc_and_broker.sql
10
+ - .framework/migrations/011_spine_system_account.sql
11
+ - .framework/migrations/020_schema_reconciliation.sql
12
+ - .framework/functions/admin-data.ts
13
+ - .framework/functions/_shared/principal.ts
14
+ - .framework/functions/_shared/permissions.ts
15
+ - .framework/functions/_shared/trigger-engine.ts
16
+ - .framework/functions/_shared/pipeline-runner.ts
17
+ - .framework/functions/system-cron.ts
18
+ - .framework/cli/lib/project-files.ts
19
+ - .framework/src/components/CustomAppLoader.tsx
20
+ - .framework/src/components/app-shell/GenericAppShell.tsx
21
+ - scripts/assemble.sh
22
+ - scripts/assemble-frontend.sh
23
+ - scripts/assemble-functions.sh
24
+ ---
25
+
26
+ # Glossary
27
+
28
+ The Spine vocabulary, in dependency order. Terms in **bold** are defined
29
+ elsewhere on this page or in the [domain model](./03-domain-model.md).
30
+
31
+ ## Identity
32
+
33
+ **account** — a tenant boundary (`public.accounts`). Every runtime record is
34
+ scoped to an `account_id`; accounts nest via `parent_id` with the
35
+ `account_paths` closure table for descendant lookups. The seeded `spine-system`
36
+ account is the platform root (see **scope**).
37
+
38
+ **person** — a human user (`public.people`), linked to Supabase `auth.users`
39
+ by `auth_uid` and placed in one account with one role. Non-first,
40
+ non-invited signups have no account until registration placement assigns one.
41
+
42
+ **principal** — the resolved identity attached to a request (`ctx.principal`),
43
+ computed per call by `.framework/functions/_shared/principal.ts`. One of:
44
+ `human` (Bearer JWT → person), `machine` (`x-api-key` header → API key, or
45
+ internal cron/trigger principal), `system` (internal invoke), or `anonymous`.
46
+ Carries `id`, `type`, `accountId`, `roles`, `scopes`, and provenance.
47
+
48
+ **role** — a named permission set (`public.roles`, unique `slug`) assigned to
49
+ a person. Roles are referenced throughout `design_schema.record_permissions`.
50
+ `system_admin` is the seeded superuser role; roles ending in `_admin` can
51
+ manage invites/members within their own account.
52
+
53
+ ## Schema
54
+
55
+ **type** — the schema definition for a record kind (`public.types`), unique
56
+ per `(kind, slug)`. Carries `design_schema` (generated into
57
+ `validation_schema`), `ownership` (`system` | `app` | `tenant`), `icon`,
58
+ `color`, `is_active`.
59
+
60
+ **design_schema** — the authoring-format JSON on a type: `fields`, `views`,
61
+ `record_permissions`, `scope`, `functionality`. See [types](../types.md) and
62
+ the worked example in [04-first-app.md](./04-first-app.md).
63
+
64
+ **validation_schema** — the runtime-format schema derived from
65
+ `design_schema` on every save by `.framework/functions/types.ts` /
66
+ `.framework/functions/_shared/schema-utils.ts`. Read-only; used to validate
67
+ record writes.
68
+
69
+ **kind** — which runtime table a type governs: `item`, `thread`, `message`,
70
+ `link`, `attachment`, `watcher`, `account`, `person` (the `ENTITY_TO_KIND`
71
+ map in `.framework/functions/admin-data.ts`).
72
+
73
+ **runtime record** — a row in one of the typed tables (`items`, `threads`,
74
+ `messages`, `links`, `attachments`, `watchers`, `accounts`, `people`). Always
75
+ has `type_id`, `account_id`, `data` jsonb, and the `design_schema`/
76
+ `validation_schema` stamped at creation.
77
+
78
+ **system field** — a `design_schema` field flagged `system: true`, stored as
79
+ a real table column and read as `record.<field>` (e.g. `title` →
80
+ `items.title`). Non-system fields live in `data` and read as
81
+ `record.data.<field>` (split implemented in
82
+ `.framework/src/components/app-shell/GenericDetailPage.tsx`).
83
+
84
+ ## Apps
85
+
86
+ **app** — a registered application (`public.apps`): `slug`, `route_prefix`,
87
+ `renderer`, `nav_items`, `min_role`/`required_roles`, `config`, `is_active`,
88
+ `is_system`. Appears in the authenticated router when it has a
89
+ `route_prefix` and `renderer != 'none'`
90
+ (`.framework/src/contexts/AppContext.tsx`).
91
+
92
+ **renderer** — how an app's UI is produced. `generic` = schema-driven shell
93
+ (`GenericAppShell` renders `nav_items` → list/detail pages from type views).
94
+ `custom` = lazy-loaded React entry (`custom/apps/<slug>/index.tsx`, falling
95
+ back to `.framework/src/apps/<slug>/index.tsx`) via
96
+ `.framework/src/components/CustomAppLoader.tsx`. `none` = registry-only, not
97
+ routed.
98
+
99
+ **manifest** — two meanings, both frozen JSON contracts: (a) an app
100
+ `manifest.json` in `custom/apps/<slug>/` declaring routes, `nav_items`,
101
+ `required_roles`, `registration`, and a `seed` block consumed by
102
+ `install-app`/`seed-app`/`update-db-app`
103
+ (`.framework/cli/commands/install-app.ts`); (b) `.spine-manifest.json`, the
104
+ project's frozen integrity manifest of per-file sha256 hashes
105
+ (`.framework/cli/lib/project-files.ts`).
106
+
107
+ ## Automation
108
+
109
+ **pipeline** — a multi-step workflow (`public.pipelines`, `stages` jsonb)
110
+ executed by `runPipeline` in
111
+ `.framework/functions/_shared/pipeline-runner.ts`. Each stage's `stage_type`
112
+ maps to a `public.actions` row or a built-in handler (`http_request`,
113
+ `send_notification`, `agent_inference`, `query_items`, …).
114
+
115
+ **trigger** — an event subscription (`public.triggers`): `event_type` +
116
+ `pipeline_id` + optional `config` filters. `admin-data` emits
117
+ `<entity>_<created|updated|deleted>` events (e.g. `item_created`); matching
118
+ triggers enqueue an execution and dispatch the pipeline via the
119
+ `pipeline-runner-background` function (requires `INTERNAL_INVOKE_SECRET`).
120
+
121
+ **timer** — a schedule (`public.timers`): `timer_type`
122
+ (`interval` | `cron` | `once`) + `pipeline_id`. The `trigger-scheduler`
123
+ Netlify scheduled function (every minute, `netlify.toml`) runs `system-cron`,
124
+ which runs due timers through `runPipeline` under a `timer:*` principal.
125
+
126
+ **integration** — a named external connection (`public.integrations`):
127
+ adapter slug + `config` + `credentials` (`env_var` reference or literal
128
+ `value`). Inbound webhooks arrive via `integration-routes`; outbound calls
129
+ via `integration-outbound` write **deliveries**.
130
+
131
+ ## AI
132
+
133
+ **prompt config** — a named, versioned prompt template
134
+ (`public.prompt_configs`) referenced by AI agents and pipeline stages.
135
+
136
+ **AI agent** — a reusable model + prompt + tool configuration
137
+ (`public.ai_agents`), invocable via `/api/ai-agents?action=run` or the
138
+ `agent_inference` pipeline stage.
139
+
140
+ **embedding** — a pgvector embedding (`public.embeddings`) queried through
141
+ the `match_embeddings`/`search_similar_embeddings` RPCs; backs semantic
142
+ search and knowledge stages.
143
+
144
+ ## Access and delivery
145
+
146
+ **API key** — a machine credential (`public.api_keys`) presented as the
147
+ `x-api-key` header; resolved by prefix and verified against a stored hash
148
+ (`.framework/functions/_shared/principal.ts`,
149
+ `.framework/functions/_shared/hash-api-key.ts`). Has `rate_limit` and usage
150
+ logged in `api_key_usage_logs`.
151
+
152
+ **delivery** — an outbound delivery attempt record
153
+ (`public.webhook_deliveries`) written by `integration-outbound`; retried by
154
+ `retry-deliveries` inside `system-cron`. See [deliveries](../deliveries.md).
155
+
156
+ **execution** — a run record: `pipeline_executions` for pipelines,
157
+ `trigger_executions` for trigger fires, `schedule_executions` for scheduled
158
+ actions. Statuses progress `queued` → `running` → `completed`/`failed`.
159
+
160
+ **audit log** — privileged-action events written by `emitAudit`
161
+ (`.framework/functions/_shared/audit.ts`) plus the `public.logs` stream —
162
+ e.g. `trigger.fired`, `app.created`, `app.version_updated`.
163
+
164
+ ## Project layout
165
+
166
+ **scope** — `design_schema.scope`: `account` (records belong to the caller's
167
+ tenant, the default) or `platform` (`admin-data` re-anchors created records
168
+ to the `spine-system` account).
169
+
170
+ **assembled** — `.assembled/`, the generated build tree:
171
+ `.assembled/src` (framework frontend + verbatim `custom/apps/<slug>/`) and
172
+ `.assembled/netlify/functions` (flattened functions for Netlify), produced by
173
+ `npm run assemble` (`scripts/assemble.sh`).
174
+
175
+ **`.framework/`** — the sealed, framework-owned tree vendored into your
176
+ project. Checksummed in `.spine-manifest.json`; overwritten by
177
+ `npx spine-framework upgrade`. See
178
+ [02-project-map.md](./02-project-map.md).
179
+
180
+ **CIL** — the Code Intelligence Layer: Spine's code-intelligence subsystem
181
+ (ingested code chunks, embeddings, and a searchable project graph) surfaced
182
+ under the admin `cil` pages (`.framework/src/pages/admin/cil/`). Optional;
183
+ your apps do not depend on it.