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
@@ -1,55 +1,88 @@
1
1
  // CIL[BEGIN stable_id="~/.framework/src/hooks/useListSchema.ts:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/src/hooks/useListSchema.ts"]
2
- // CIL[DOC-AUDIENCE audience="frontend"]
3
- // CIL[DOC-CONTEXT module="useListSchema" layer="hooks" related_files=".framework/src/lib/api.ts,.framework/src/types/types.ts"]
4
- // CIL[DOC-CONTRACT inputs="none" outputs="React hooks, apiFetch and DesignSchema/View imports available to the module" errors="none" side_effects="none"]
5
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
6
- // CIL[DOC-MACRO purpose="React hook module for loading entity list design schemas"]
7
- // CIL[DOC-MICRO logic_summary="Imports useState, useEffect, apiFetch and local DesignSchema/View types" notable_decisions="[]"]
8
- // CIL[DOC-RESPONSIBILITY responsibility="Provide the useListSchema hook and its option/result type definitions"]
9
- // CIL[DOC-STABILITY stability="stable"]
2
+ /**
3
+ * @module useListSchema
4
+ * @audience both
5
+ * @layer shared-core
6
+ * @stability stable
7
+ *
8
+ * This module provides hooks for managing and interacting with list schemas in the application. It utilizes React's state and effect hooks to fetch and update schema data from an API. INVARIANT: The component using this hook must be wrapped in a provider that supplies the necessary context for API calls.
9
+ *
10
+ * @seeAlso apiFetch (handles API requests).
11
+ * @seeAlso DesignSchema (defines the structure of the schema data).
12
+ * @seeAlso View (represents the UI components that utilize the schema).
13
+ *
14
+ * @cil-generated
15
+ */
16
+
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
10
25
 
11
26
  import { useState, useEffect } from 'react'
12
27
  import { apiFetch } from '../lib/api'
13
28
  import { DesignSchema, View } from '../types/types'
14
- // CIL[DOC-VECTOR type="context" content="purpose='React hook module for loading entity list design schemas'; No verified external callers; imports: .framework/src/lib/api.ts,.framework/src/types/types.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
29
  // CIL[END stable_id="~/.framework/src/hooks/useListSchema.ts:module_header:module_header"]
21
30
 
22
31
 
23
32
 
24
33
 
34
+
35
+
36
+
37
+
38
+
39
+
40
+
41
+
42
+
43
+
44
+
45
+
46
+
47
+
48
+
25
49
  // CIL[BEGIN stable_id="~/.framework/src/hooks/useListSchema.ts:UseListSchemaOptions:interface" type="interface" identity="UseListSchemaOptions" parent="~/.framework/src/hooks/useListSchema.ts"]
26
- // CIL[DOC-MACRO purpose="Defines the input options for the useListSchema hook"]
27
- // CIL[DOC-RESPONSIBILITY responsibility="Declare entity and optional viewSlug used to resolve the list schema"]
28
- // CIL[DOC-CONTEXT module="useListSchema" layer="hooks" related_files=".framework/src/hooks/useListSchema.ts,.framework/src/lib/api.ts,.framework/src/types/types.ts"]
29
- // CIL[DOC-CONTRACT inputs="N/A" outputs="N/A" errors="N/A" side_effects="N/A"]
30
- // CIL[DOC-MICRO logic_summary="entity: string and viewSlug?: string" notable_decisions="[]"]
31
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
32
- // CIL[DOC-STABILITY stability="stable"]
50
+ /**
51
+ * The UseListSchemaOptions interface defines the options for using a list schema in the framework, allowing for the specification of an entity and an optional view slug for enhanced flexibility in list management.
52
+ *
53
+ * @sideEffects none
54
+ * @stability internal
55
+ * @cil-generated
56
+ */
33
57
  interface UseListSchemaOptions {
34
58
  entity: string
35
59
  viewSlug?: string
36
60
  }
37
- // CIL[DOC-VECTOR type="context" content="purpose='Defines the input options for the useListSchema hook'; No verified external callers; imports: .framework/src/lib/api.ts,.framework/src/types/types.ts"]
38
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
39
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
40
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
41
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
42
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
43
61
  // CIL[END stable_id="~/.framework/src/hooks/useListSchema.ts:UseListSchemaOptions:interface"]
44
62
 
63
+
64
+
65
+
66
+
67
+
68
+
69
+
70
+
71
+
72
+
73
+
74
+
75
+
76
+
77
+
45
78
  // CIL[BEGIN stable_id="~/.framework/src/hooks/useListSchema.ts:UseListSchemaResult:interface" type="interface" identity="UseListSchemaResult" parent="~/.framework/src/hooks/useListSchema.ts"]
46
- // CIL[DOC-MACRO purpose="Defines the return shape of the useListSchema hook"]
47
- // CIL[DOC-RESPONSIBILITY responsibility="Declare schema, view, loading state, error and refetch callback"]
48
- // CIL[DOC-CONTEXT module="useListSchema" layer="hooks" related_files=".framework/src/hooks/useListSchema.ts,.framework/src/lib/api.ts,.framework/src/types/types.ts"]
49
- // CIL[DOC-CONTRACT inputs="N/A" outputs="N/A" errors="N/A" side_effects="N/A"]
50
- // CIL[DOC-MICRO logic_summary="schema, view, loading, error and refetch fields" notable_decisions="[]"]
51
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
52
- // CIL[DOC-STABILITY stability="stable"]
79
+ /**
80
+ * The UseListSchemaResult interface defines the structure of the result returned by the useListSchema hook, which is used to manage and retrieve schema data in a React application. It provides information about the loading state, any errors, and a method to refetch the data.
81
+ *
82
+ * @sideEffects none
83
+ * @stability internal
84
+ * @cil-generated
85
+ */
53
86
  interface UseListSchemaResult {
54
87
  schema: DesignSchema | null
55
88
  view: View | null
@@ -57,22 +90,39 @@ interface UseListSchemaResult {
57
90
  error: string | null
58
91
  refetch: () => void
59
92
  }
60
- // CIL[DOC-VECTOR type="context" content="purpose='Defines the return shape of the useListSchema hook'; No verified external callers; imports: .framework/src/lib/api.ts,.framework/src/types/types.ts"]
61
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
62
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
63
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
64
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
65
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
66
93
  // CIL[END stable_id="~/.framework/src/hooks/useListSchema.ts:UseListSchemaResult:interface"]
67
94
 
95
+
96
+
97
+
98
+
99
+
100
+
101
+
102
+
103
+
104
+
105
+
106
+
107
+
108
+
109
+
68
110
  // CIL[BEGIN stable_id="~/.framework/src/hooks/useListSchema.ts:useListSchema:hook" type="hook" identity="useListSchema" parent="~/.framework/src/hooks/useListSchema.ts"]
69
- // CIL[DOC-CONTEXT module="useListSchema" layer="hooks" related_files=".framework/src/hooks/useListSchema.ts,.framework/src/lib/api.ts,.framework/src/types/types.ts"]
70
- // CIL[DOC-CONTRACT inputs="options: UseListSchemaOptions" outputs="UseListSchemaResult" errors="Network or API errors set the error string" side_effects="Calls apiFetch on mount and when entity/viewSlug changes; updates local state"]
71
- // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
72
- // CIL[DOC-MACRO purpose="React hook that loads the design schema and view definition for an entity list"]
73
- // CIL[DOC-MICRO logic_summary="Fetches a sample record to read stamped design_schema; falls back to type lookup and generic fallback views; supports JWT retry" notable_decisions="[]"]
74
- // CIL[DOC-RESPONSIBILITY responsibility="Fetch and resolve the list design schema and selected view for a given entity"]
75
- // CIL[DOC-STABILITY stability="stable"]
111
+ /**
112
+ * The useListSchema hook fetches and manages the schema and view for a specified entity in a list format, handling loading states and errors while providing a fallback schema if no data is available.
113
+ *
114
+ * @macro Custom React hook for managing entity list schemas.
115
+ * @micro Utilizes asynchronous API calls to fetch data and updates state based on the response.
116
+ * @inputSpec
117
+ * - options: UseListSchemaOptions (required) — configuration options including entity and optional viewSlug.
118
+ * @outputSpec UseListSchemaResult — an object containing schema, view, loading state, and error message.
119
+ * @throws Error — failed to fetch sample record or invalid authentication.
120
+ * @sideEffects API calls to /api/admin-data and /api/types for fetching schema data.
121
+ * @stability internal
122
+ * @calls apiFetch
123
+ * @errorHandling Retries fetching schema on specific authentication errors.
124
+ * @cil-generated
125
+ */
76
126
  export function useListSchema(options: UseListSchemaOptions): UseListSchemaResult {
77
127
  const { entity, viewSlug = 'default_list' } = options
78
128
 
@@ -149,12 +199,12 @@ export function useListSchema(options: UseListSchemaOptions): UseListSchemaResul
149
199
  let resolvedSchema: DesignSchema | null = null
150
200
 
151
201
  if (kind) {
152
- const typeResp = await apiFetch(`/api/types?kind=${kind}&limit=1`)
202
+ const typeResp = await apiFetch(`/api/types?action=list&kind=${kind}`)
153
203
  if (typeResp.ok) {
154
204
  const typeData = await typeResp.json()
155
- const typeRecord = typeData.data?.[0]
156
- if (typeRecord?.design_schema) {
157
- resolvedSchema = typeRecord.design_schema as DesignSchema
205
+ const typeRecords = Array.isArray(typeData.data) ? typeData.data : []
206
+ if (typeRecords.length === 1 && typeRecords[0]?.design_schema) {
207
+ resolvedSchema = typeRecords[0].design_schema as DesignSchema
158
208
  }
159
209
  }
160
210
  }
@@ -243,10 +293,10 @@ export function useListSchema(options: UseListSchemaOptions): UseListSchemaResul
243
293
  refetch: fetchSchema
244
294
  }
245
295
  }
246
- // CIL[DOC-VECTOR type="context" content="purpose='React hook that loads the design schema and view definition for an entity list'; No verified external callers; imports: .framework/src/lib/api.ts,.framework/src/types/types.ts"]
247
- // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
248
- // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
249
- // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
250
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
251
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
252
- // CIL[END stable_id="~/.framework/src/hooks/useListSchema.ts:useListSchema:hook"]
296
+ // CIL[END stable_id="~/.framework/src/hooks/useListSchema.ts:useListSchema:hook"]
297
+
298
+
299
+
300
+
301
+
302
+
@@ -0,0 +1,57 @@
1
+ ---
2
+ title: Spine Instruction Book
3
+ audience: developers, agents
4
+ kind: index
5
+ verified_against: 4d9d52a
6
+ verified_on: 2026-10-29
7
+ source_files:
8
+ - .framework/src/instructions/
9
+ ---
10
+
11
+ # Spine Instruction Book
12
+
13
+ This directory is the instruction book shipped with the `spine-framework` npm
14
+ package. It is written for two readers: **developers** building on Spine, and
15
+ **agents** (human or AI) operating a Spine deployment. Every file must pass
16
+ `npm run docs:lint` — see `docs/audit/docs-spec.md` in the repo for the
17
+ authoring spec.
18
+
19
+ ## Structure
20
+
21
+ | Section | Kind | Contents |
22
+ |---|---|---|
23
+ | `guide/` | guide | End-to-end walkthroughs (install, first app, deploy). |
24
+ | `concepts/` | concept | Mental models — tenancy, permissions, types, runtime vs config. |
25
+ | `tasks/` | task | Single-goal procedures with prerequisites and verification steps. |
26
+ | `reference/` | reference | Exhaustive lookups — env vars, CLI commands, API endpoints, schema enums. |
27
+ | `operations/` | ui | Admin-UI pages and operational runbooks. |
28
+ | `internal/` | * | Repo-only/internal docs; exempt from the archived-docs and CIL-tooling reference rules. |
29
+ | *(root)* | entity | One file per Spine entity (`types`, `apps`, `roles`, …). |
30
+
31
+ ## Reading order — developers
32
+
33
+ 1. `guide/` getting-started, then `concepts/` tenancy & permissions.
34
+ 2. The `entity` files for the types you will create (`types.md` first).
35
+ 3. `tasks/` for the specific job at hand; `reference/` for exact spellings.
36
+
37
+ ## Reading order — agents
38
+
39
+ 1. `concepts/` — know what a Spine account, type, and record are.
40
+ 2. `entity` files — the 7-section template below tells you what each entity is
41
+ for, its fields, minimal/full configuration, a worked example, the core
42
+ files, and agent-specific cautions.
43
+ 3. `operations/` — how to drive the admin UI; `internal/` — repo-only notes.
44
+
45
+ ## The 7-section entity template
46
+
47
+ Every `entity` or `ui` doc uses the same seven `##` sections, in order:
48
+
49
+ 1. `## What this is for`
50
+ 2. `## Fields and settings`
51
+ 3. `## Minimal configuration`
52
+ 4. `## Full configuration`
53
+ 5. `## Example`
54
+ 6. `## Core files`
55
+ 7. `## Agent notes`
56
+
57
+ `docs-lint` enforces the heading set verbatim.
@@ -0,0 +1,69 @@
1
+ ---
2
+ title: AI Agents
3
+ audience: both
4
+ kind: entity
5
+ verified_against: e13127d
6
+ verified_on: 2026-10-30
7
+ source_files:
8
+ - .framework/functions/ai-agents.ts
9
+ - .framework/functions/_shared/agent-runner.ts
10
+ - .framework/src/pages/admin/AIAgentsPage.tsx
11
+ - .framework/src/pages/admin/AIAgentDetailPage.tsx
12
+ ---
13
+
14
+ ## What this is for
15
+
16
+ An **AI agent** is a reusable model + prompt + tool configuration that Spine invokes from pipelines, triggers, and chat interfaces. It defines how an LLM behaves, which tools it can call, and its guardrails.
17
+
18
+ ## Fields and settings
19
+
20
+ - **Name** — string. Display name used in lists and by callers; required.
21
+ - **Type** — select: `chat`, `analysis`, `automation`, `custom`. Categorizes and routes the agent; defaults to `chat`.
22
+ - **Model** — string. Stored in `model_config.model`. Blank falls back to `LLM_DEFAULT_MODEL` env then `gpt-4o` at inference time — set it explicitly so the behavior isn't env-dependent.
23
+ - **Max Tokens** — number. Maximum response length; empty values can cause provider errors.
24
+ - **Temperature** — number 0–2. Lower = deterministic, higher = random; out-of-range values may be rejected by the provider.
25
+ - **Description** — string, optional.
26
+ - **System Prompt** — text. The agent's personality, instructions, and constraints. Empty = no system message sent.
27
+ - **App ID** — select, optional. Owning app; blank = account-scoped.
28
+ - **Tools (one per line)** — newline-separated tool names the agent may invoke. Names must match registered tools exactly.
29
+ - **Capabilities / Constraints / Metadata (JSON)** — optional objects: feature flags, guardrails, free-form metadata. Invalid JSON blocks save.
30
+ - **Active** — checkbox. Inactive agents are hidden from callers and cannot be invoked.
31
+
32
+ **Downstream effects**
33
+
34
+ - Pipelines, triggers, and chat UIs reference agents by ID — changing the model changes their output everywhere.
35
+ - Tool names must match the tool registry exactly; unknown names produce runtime errors when invoked.
36
+ - `system_prompt` composes with the caller's prompt config — conflicting instructions between the two cause unpredictable behavior.
37
+
38
+ ## Minimal configuration
39
+
40
+ ```json
41
+ {
42
+ "name": "Triage agent",
43
+ "agent_type": "automation",
44
+ "model_config": { "model": "gpt-4o", "temperature": 0.3, "max_tokens": 2000 },
45
+ "system_prompt": "You classify inbound support tickets...",
46
+ "is_active": true
47
+ }
48
+ ```
49
+
50
+ ## Full configuration
51
+
52
+ Adds `tools` (the registered tool names the agent may call), `capabilities` (e.g. `{ "json_mode": true, "streaming": false }`), `constraints` (e.g. `{ "max_tool_calls": 5, "disallowed": ["delete"] }`), and `metadata`.
53
+
54
+ ## Example
55
+
56
+ A support app's triage agent (`agent_type: "automation"`, low temperature) classifies new tickets and calls a `set_field` tool to tag them; its companion chat agent (`agent_type: "chat"`, higher temperature, `tools: [search_kb]`) drafts replies for human review.
57
+
58
+ ## Core files
59
+
60
+ - `.framework/functions/ai-agents.ts` — API
61
+ - `.framework/functions/ai-interactions.ts` — invocation/interaction records
62
+ - `.framework/src/pages/admin/AIAgentsPage.tsx` / `AIAgentDetailPage.tsx` — admin UI
63
+ - Table: `public.ai_agents`
64
+
65
+ ## Agent notes
66
+
67
+ - The detail form stores model settings under `model_config` — a flat `model` field on the record will be ignored by callers.
68
+ - Pair agents with a `prompt_configs` entry for the prompt body; the agent record holds behavior, the prompt config holds text.
69
+ - Validate JSON fields before saving — a parse failure silently keeps the previous config.
@@ -0,0 +1,80 @@
1
+ ---
2
+ title: Threshold Alerts
3
+ audience: both
4
+ kind: entity
5
+ verified_against: e13127d
6
+ verified_on: 2026-10-30
7
+ source_files:
8
+ - .framework/src/pages/admin/AlertsConfigPage.tsx
9
+ - .framework/functions/admin-data.ts
10
+ - .framework/functions/system-cron.ts
11
+ - .framework/functions/observability.ts
12
+ ---
13
+
14
+ ## What this is for
15
+
16
+ **Threshold Alerts** (`/spine-framework/admin/observability/alerts`) manages alert rules over platform metrics. Each alert is a runtime `items` record of type `threshold_alert`, edited through the generic `admin-data` API. `system-cron` evaluates them every tick; a breach emits a `threshold.breached` log event (visible under Logs and on the Observability dashboard) and can invoke a linked pipeline.
17
+
18
+ ## Fields and settings
19
+
20
+ - **Title / Description** — record `title` and `description` shown in the list.
21
+ - **Status** — `active` or `inactive`; toggled per-row (writes both `status` and `data.is_active`).
22
+ - **Metric** (`data.metric`) — `error_rate` (%), `latency_p95` (ms), or `pipeline_failure_rate` (%).
23
+ - **Operator** (`data.operator`) — `gt` (>) or `lt` (<).
24
+ - **Value** (`data.value`) — the threshold number, in the metric's unit.
25
+ - **Window** (`data.window_minutes`) — lookback window the metric is computed over.
26
+ - **Pipeline** (`data.pipeline_id`) — optional pipeline invoked when the threshold is breached; populated from `/api/pipelines?action=list`.
27
+ - Stats cards — Total, Active, Inactive, With Pipeline.
28
+
29
+ **Downstream effects**
30
+
31
+ - Alerts are plain `items` records — create/edit/delete goes through `/api/admin-data?entity=items` with `type_id: "threshold_alert"`, so they inherit the type's `record_permissions` and validation.
32
+ - `system-cron` evaluates each active alert every tick against the observability metrics; breaching emits `threshold.breached` log events.
33
+ - An alert without a `pipeline_id` still logs breach events — the pipeline link is what turns a breach into an action.
34
+ - Deleting an alert hard-removes the record; there is no history table beyond `logs`.
35
+
36
+ ## Minimal configuration
37
+
38
+ ```
39
+ Title: High error rate
40
+ data.metric: error_rate · data.operator: gt · data.value: 5
41
+ data.window_minutes: 60 · is_active: true
42
+ ```
43
+
44
+ ## Full configuration
45
+
46
+ ```json
47
+ {
48
+ "type_id": "threshold_alert",
49
+ "title": "P95 latency above 2s",
50
+ "description": "Page on sustained slow requests",
51
+ "status": "active",
52
+ "data": {
53
+ "metric": "latency_p95",
54
+ "operator": "gt",
55
+ "value": 2000,
56
+ "window_minutes": 30,
57
+ "pipeline_id": "<pipeline uuid>",
58
+ "is_active": true
59
+ }
60
+ }
61
+ ```
62
+
63
+ ## Example
64
+
65
+ A platform team keeps three alerts: `error_rate > 5% / 60min` paging the on-call pipeline, `latency_p95 > 2000ms / 30min` opening an incident thread, and `pipeline_failure_rate > 10% / 15min` running a diagnostics pipeline that snapshots recent executions.
66
+
67
+ ## Core files
68
+
69
+ - `.framework/src/pages/admin/AlertsConfigPage.tsx` — this page (modal create/edit, toggle, delete)
70
+ - `.framework/functions/admin-data.ts` — CRUD backend (`entity=items`, `type_id=threshold_alert`)
71
+ - `.framework/functions/system-cron.ts` — per-tick threshold evaluation, emits `threshold.breached`
72
+ - `.framework/functions/observability.ts` — `error_rate`/`latency_percentiles`/`pipeline_stats` metrics the alerts compare against
73
+ - Table: `public.items` rows of type `threshold_alert`
74
+
75
+ ## Agent notes
76
+
77
+ - The type slug is `threshold_alert` and the config lives under `data.*` — do not confuse it with the `pipelines`/`triggers` config tables.
78
+ - `status` and `data.is_active` are written together by the toggle; editing the record elsewhere can desync them — the evaluator reads `data.is_active`.
79
+ - Breach events are the audit trail: filter Logs by `threshold.breached` to see when and how often an alert fired.
80
+ - There is no dedupe/cooldown field — a breached metric re-fires each tick; build any cooldown into the linked pipeline.
@@ -0,0 +1,87 @@
1
+ ---
2
+ title: API Keys
3
+ audience: both
4
+ kind: entity
5
+ verified_against: e13127d
6
+ verified_on: 2026-10-30
7
+ source_files:
8
+ - .framework/functions/api-keys.ts
9
+ - .framework/functions/_shared/hash-api-key.ts
10
+ - .framework/functions/_shared/principal.ts
11
+ - .framework/functions/_shared/logging.ts
12
+ - .framework/src/pages/admin/APIKeysPage.tsx
13
+ - .framework/src/pages/admin/APIKeyDetailPage.tsx
14
+ ---
15
+
16
+ ## What this is for
17
+
18
+ An **API key** authenticates callers to Spine — integrations, MCP servers, CLI tooling, and service-to-service calls. A key controls which callers are accepted, how fast they can call, and which permissions they carry.
19
+
20
+ ## Fields and settings
21
+
22
+ - **Name** *(required)* — human-readable label; missing name blocks creation.
23
+ - **Integration ID** — optional UUID of the integration this key serves.
24
+ - **App ID** — optional UUID/slug of the owning app (server resolves slugs via `resolveAppUuid`).
25
+ - **Key Type** — `inbound` (external callers into Spine), `outbound` (Spine calling out), `internal` (service-to-service), `cli` (scripts/tooling). Determines how the key is validated.
26
+ - **Key Prefix** — derived server-side: the raw key is `sk_<uuid>` and `key_prefix` stores its first 8 characters for lookup. Not a form field.
27
+ - **Rate Limit (requests/min)** — `rate_limit`, UI range 1–10000. Enforced per key inside `rate_limit_window_seconds` (default 60s, overridable via key `config`). An unset/`0` value falls back to the default 100 — it does not block requests.
28
+ - **Expires At** — optional date; after it the key is rejected.
29
+ - **Machine Type** — machine principal type, e.g. `integration`.
30
+ - **Internal** — marks the key for internal service-to-service use.
31
+ - **Active** — inactive keys are rejected on every call.
32
+ - **Permissions / Scopes / Metadata (JSON)** — `permissions` and `scopes` are string arrays (validated against required permissions on `action=validate`); `metadata` is free-form. Invalid JSON fails creation.
33
+
34
+ **Downstream effects**
35
+
36
+ - The gateway validates `key_prefix` + `key_hash` on every call — inactive, expired, or over-limit keys are rejected.
37
+ - The raw key is returned **once** at create (`raw_key` in the response envelope). It is never stored or returned again — `key_value`/`key_hash` are stripped from all API responses (S-001/F-040).
38
+ - The API has no update action (list/get/create plus `validate`, `revoke`, `usage-logs`) — rotate = create new + revoke old.
39
+ - Keys still referenced in local MCP configs or scripts fail immediately when revoked/deactivated.
40
+
41
+ ## Minimal configuration
42
+
43
+ ```json
44
+ {
45
+ "name": "CI deploy key",
46
+ "key_type": "cli",
47
+ "rate_limit": 60,
48
+ "is_active": true
49
+ }
50
+ ```
51
+
52
+ ## Full configuration
53
+
54
+ ```json
55
+ {
56
+ "name": "Workbench MCP",
57
+ "key_type": "inbound",
58
+ "app_id": "workbench",
59
+ "rate_limit": 600,
60
+ "expires_at": "2027-01-01",
61
+ "machine_type": "integration",
62
+ "is_active": true,
63
+ "permissions": ["admin-data:read"],
64
+ "scopes": ["admin-data:read", "logs:read"],
65
+ "metadata": { "env": "dev" }
66
+ }
67
+ ```
68
+
69
+ ## Example
70
+
71
+ A local MCP server authenticates with an `inbound` key scoped to read-only admin-data calls; a separate `cli` key (low rate limit) backs the `spine-framework` CLI. A leaked key gets rotated by creating a replacement and revoking the old one — the audit found a plaintext-stored legacy key and deactivated it (S-001/S-003).
72
+
73
+ ## Core files
74
+
75
+ - `.framework/functions/api-keys.ts` — API (create/list/get + `validate`/`revoke`/`usage-logs` actions; mints `sk_<uuid>` raw key)
76
+ - `.framework/functions/_shared/hash-api-key.ts` — `hashApiKey`, `verifyApiKey` (pbkdf2), `omitSecretFields` (strips `key_value`/`key_hash`)
77
+ - `.framework/functions/_shared/logging.ts` — `resolveAppUuid` (app slug → UUID on create)
78
+ - `.framework/functions/_shared/principal.ts` — per-request key resolution (`x-api-key` → prefix lookup → pbkdf2 verify → per-key + per-IP rate limit)
79
+ - `.framework/cli/context.ts` — CLI auth path (F-042)
80
+ - `.framework/src/pages/admin/APIKeysPage.tsx` / `APIKeyDetailPage.tsx` — admin UI
81
+ - Table: `public.api_keys`
82
+
83
+ ## Agent notes
84
+
85
+ - Copy `raw_key` at creation — there is no "show key" later. Treat any key whose value was ever visible as burned.
86
+ - Prefer short `expires_at` + documented `metadata.env` over long-lived keys.
87
+ - `key_type: cli` + a `permissions` array is the documented path for scripted/agent access (see S-002 — a first-class scriptable login is still pending).
@@ -0,0 +1,77 @@
1
+ ---
2
+ title: Apps
3
+ audience: both
4
+ kind: entity
5
+ verified_against: e13127d
6
+ verified_on: 2026-10-30
7
+ source_files:
8
+ - .framework/functions/apps.ts
9
+ - .framework/src/pages/admin/AppsPage.tsx
10
+ - .framework/src/pages/admin/AppDetailPage.tsx
11
+ - .framework/migrations/003_core_system_data.sql
12
+ - .framework/migrations/013_get_account_apps_role_filter.sql
13
+ ---
14
+
15
+ ## What this is for
16
+
17
+ An **app** is a registered application in Spine. The registry controls navigation visibility, who can open the app (min role), how it renders (generic vs custom), and the JSON configuration the app or its types consume at runtime.
18
+
19
+ ## Fields and settings
20
+
21
+ - **Name** — string. Display name in the app switcher and registry.
22
+ - **Slug** — string. Unique identifier; set at creation, rarely changed. Routes and API scoping depend on it.
23
+ - **Description** — string, optional. Short text shown in the app list.
24
+ - **App Type** — select: `system`, `custom`, `marketplace`. Drives how the platform treats the app.
25
+ - **Source** — select: `system`, `custom`, `marketplace`. Tracks where the package came from.
26
+ - **Min Role** — select: `member`, `admin`, `owner`. Lowest role that can see/open the app.
27
+ - **Version** — string. Current version shown in the registry.
28
+ - **Active** — boolean. Inactive apps are hidden and cannot be opened.
29
+ - **System** — boolean. Protects the app from tenant-level deletion.
30
+ - **Icon / Color** — UI presentation for the app tile.
31
+ - **Route Prefix** — string, optional. URL prefix (defaults to `/slug`).
32
+ - **Renderer** — select: `generic` (renders list/detail from type `design_schema.views`), `custom` (app renders its own pages), `none`.
33
+ - **Config (JSON)** — `config` column; runtime config for the app or its generic renderer.
34
+ - **Nav Items (JSON)** — array of navigation items for the app shell.
35
+ - **Integration Deps (JSON)** — array of integration slugs the app depends on.
36
+ - **Metadata (JSON)** — free-form metadata.
37
+
38
+ **Downstream effects**
39
+
40
+ - The app shell reads `slug`, `route_prefix`, `min_role`, `is_active`, `icon`, `color`, `nav_items` to build navigation and gate access.
41
+ - `renderer = generic` requires every served type to have complete `views` in its `design_schema`.
42
+ - `min_role` raises the floor for the whole app — setting `admin` hides it from members even if record permissions would allow reads.
43
+
44
+ ## Minimal configuration
45
+
46
+ ```json
47
+ {
48
+ "slug": "my-app",
49
+ "name": "My App",
50
+ "app_type": "custom",
51
+ "source": "custom",
52
+ "renderer": "custom",
53
+ "is_active": true,
54
+ "min_role": "member"
55
+ }
56
+ ```
57
+
58
+ ## Full configuration
59
+
60
+ Adds `version`, `icon`, `color`, `route_prefix`, `config` (feature flags, default views), `nav_items` (grouped sidebar entries), `integration_deps` (e.g. `["openai", "sendgrid"]`), and `metadata` (author, homepage, tags).
61
+
62
+ ## Example
63
+
64
+ A support app registers with `renderer: "custom"`, `route_prefix: "/answer-once"`, `min_role: "member"`, and `integration_deps: ["openai"]` — the admin renders its own pages but still uses `/api/admin-data` for record CRUD and `types` for its ticket/thread types.
65
+
66
+ ## Core files
67
+
68
+ - `.framework/functions/apps.ts` — API (list/get/create/update/delete)
69
+ - `.framework/src/pages/admin/AppsPage.tsx` / `AppDetailPage.tsx` — admin UI
70
+ - `.framework/src/components/app-shell/` — shell, generic renderer, app registry
71
+ - Table: `public.apps` (+ `get_account_apps` RPC for counts)
72
+
73
+ ## Agent notes
74
+
75
+ - `renderer = "custom"` still needs `fields` + `record_permissions` on its types so `admin-data` can stamp and validate records.
76
+ - Slug appears in API envelopes and `x-app-id` headers — renaming an in-use slug breaks logging attribution and callers.
77
+ - `marketplace` as a type/source value is under review (F-031) — prefer `custom` for new apps.