spine-framework 0.4.4 → 0.5.0-rc.5

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 (305) 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/install-app.ts +183 -13
  8. package/.framework/cli/commands/migrate.ts +36 -30
  9. package/.framework/cli/commands/migrations.ts +16 -56
  10. package/.framework/cli/commands/upgrade.ts +35 -0
  11. package/.framework/cli/commands/validate-app.ts +127 -1
  12. package/.framework/cli/commands/validate-schema.ts +147 -0
  13. package/.framework/cli/context.ts +223 -110
  14. package/.framework/cli/index.ts +6 -0
  15. package/.framework/cli/lib/project-files.ts +241 -1
  16. package/.framework/functions/_shared/app-manifest.ts +2 -0
  17. package/.framework/functions/_shared/hash-api-key.ts +183 -79
  18. package/.framework/functions/_shared/logging.ts +562 -224
  19. package/.framework/functions/_shared/middleware.ts +47 -44
  20. package/.framework/functions/_shared/permissions.ts +4 -0
  21. package/.framework/functions/admin-data.ts +51 -28
  22. package/.framework/functions/ai-agents.ts +10 -6
  23. package/.framework/functions/api-keys.ts +301 -122
  24. package/.framework/functions/apps.ts +63 -29
  25. package/.framework/functions/cil-ingest.ts +48 -15
  26. package/.framework/functions/debug-auth.ts +14 -8
  27. package/.framework/functions/deliveries.ts +39 -12
  28. package/.framework/functions/embeddings.ts +149 -78
  29. package/.framework/functions/integration-outbound.ts +67 -27
  30. package/.framework/functions/integrations.ts +254 -127
  31. package/.framework/functions/logs.ts +273 -133
  32. package/.framework/functions/observability.ts +278 -148
  33. package/.framework/functions/pipeline-executions.ts +1 -1
  34. package/.framework/functions/pipelines.ts +14 -9
  35. package/.framework/functions/prompt-configs.ts +7 -4
  36. package/.framework/functions/roles.ts +8 -5
  37. package/.framework/functions/security.ts +30 -17
  38. package/.framework/functions/system-cron.ts +240 -127
  39. package/.framework/functions/tests.ts +7 -6
  40. package/.framework/functions/timers.ts +310 -107
  41. package/.framework/functions/triggers.ts +28 -13
  42. package/.framework/functions/types.ts +13 -10
  43. package/.framework/migrations/069_log_stats_window.sql +54 -0
  44. package/.framework/migrations/070_app_type_schema_rpcs.sql +166 -0
  45. package/.framework/migrations/071_timer_interval_keys.sql +96 -0
  46. package/.framework/migrations/072_slug_autofill.sql +77 -0
  47. package/.framework/migrations/073_seed_member_roles.sql +26 -0
  48. package/.framework/migrations/074_app_route_prefix_domains.sql +168 -0
  49. package/.framework/migrations/075_security_definer_grants.sql +157 -0
  50. package/.framework/src/apps/admin/index.tsx +1141 -775
  51. package/.framework/src/components/ErrorBoundary.tsx +136 -0
  52. package/.framework/src/components/admin/AdminListPage.tsx +81 -73
  53. package/.framework/src/components/admin/AdminSidebar.tsx +88 -79
  54. package/.framework/src/components/admin/EntitySelect.tsx +181 -0
  55. package/.framework/src/components/admin/PageInstructions.tsx +86 -127
  56. package/.framework/src/components/app-shell/GenericDetailPage.tsx +37 -13
  57. package/.framework/src/components/app-shell/GenericListPage.tsx +28 -32
  58. package/.framework/src/components/layout/Sidebar.tsx +300 -177
  59. package/.framework/src/components/runtime/DataDetailPage.tsx +67 -35
  60. package/.framework/src/components/runtime/DataHeader.tsx +96 -48
  61. package/.framework/src/components/runtime/DataListPage.tsx +3 -26
  62. package/.framework/src/components/runtime/DataStats.tsx +10 -10
  63. package/.framework/src/components/runtime/DataTable.tsx +12 -10
  64. package/.framework/src/components/ui/sheet.tsx +24 -26
  65. package/.framework/src/components/ui/textarea.tsx +74 -48
  66. package/.framework/src/contexts/AppContext.tsx +5 -12
  67. package/.framework/src/contexts/AuthContext.tsx +17 -9
  68. package/.framework/src/hooks/useApps.ts +18 -22
  69. package/.framework/src/hooks/useEntityList.ts +12 -9
  70. package/.framework/src/hooks/useListSchema.ts +108 -58
  71. package/.framework/src/instructions/README.md +74 -0
  72. package/.framework/src/instructions/accounts.md +97 -0
  73. package/.framework/src/instructions/ai-agents.md +69 -0
  74. package/.framework/src/instructions/alerts.md +80 -0
  75. package/.framework/src/instructions/api-keys.md +87 -0
  76. package/.framework/src/instructions/apps.md +77 -0
  77. package/.framework/src/instructions/concepts/ai-and-prompts.md +150 -0
  78. package/.framework/src/instructions/concepts/apps-and-renderers.md +228 -0
  79. package/.framework/src/instructions/concepts/auth-and-api-keys.md +133 -0
  80. package/.framework/src/instructions/concepts/automation.md +186 -0
  81. package/.framework/src/instructions/concepts/concurrency-and-idempotency.md +125 -0
  82. package/.framework/src/instructions/concepts/core-vs-custom.md +124 -0
  83. package/.framework/src/instructions/concepts/design-schema.md +152 -0
  84. package/.framework/src/instructions/concepts/integrations-and-webhooks.md +127 -0
  85. package/.framework/src/instructions/concepts/observability.md +116 -0
  86. package/.framework/src/instructions/concepts/permissions.md +150 -0
  87. package/.framework/src/instructions/concepts/runtime-records.md +111 -0
  88. package/.framework/src/instructions/concepts/scope-and-accounts.md +112 -0
  89. package/.framework/src/instructions/concepts/spine-way.md +172 -0
  90. package/.framework/src/instructions/deliveries.md +59 -0
  91. package/.framework/src/instructions/guide/00-orientation.md +106 -0
  92. package/.framework/src/instructions/guide/01-install-and-first-run.md +253 -0
  93. package/.framework/src/instructions/guide/02-project-map.md +147 -0
  94. package/.framework/src/instructions/guide/03-domain-model.md +223 -0
  95. package/.framework/src/instructions/guide/04-first-app.md +227 -0
  96. package/.framework/src/instructions/guide/05-glossary.md +183 -0
  97. package/.framework/src/instructions/integrations.md +96 -0
  98. package/.framework/src/instructions/internal/cil-markers.md +83 -0
  99. package/.framework/src/instructions/internal/docs-contract.md +158 -0
  100. package/.framework/src/instructions/invites.md +60 -0
  101. package/.framework/src/instructions/kb.md +80 -0
  102. package/.framework/src/instructions/logs.md +77 -0
  103. package/.framework/src/instructions/notifications.md +77 -0
  104. package/.framework/src/instructions/observability.md +61 -0
  105. package/.framework/src/instructions/operations/deployment.md +115 -0
  106. package/.framework/src/instructions/operations/migrations.md +125 -0
  107. package/.framework/src/instructions/operations/security-checklist.md +170 -0
  108. package/.framework/src/instructions/operations/troubleshooting.md +170 -0
  109. package/.framework/src/instructions/operations/upgrade.md +116 -0
  110. package/.framework/src/instructions/people.md +91 -0
  111. package/.framework/src/instructions/pipeline-executions.md +62 -0
  112. package/.framework/src/instructions/pipelines.md +78 -0
  113. package/.framework/src/instructions/prompts.md +95 -0
  114. package/.framework/src/instructions/reference/api/admin-data.md +162 -0
  115. package/.framework/src/instructions/reference/api/auth.md +113 -0
  116. package/.framework/src/instructions/reference/api/errors-and-envelopes.md +113 -0
  117. package/.framework/src/instructions/reference/app-manifest.md +184 -0
  118. package/.framework/src/instructions/reference/cli.md +124 -0
  119. package/.framework/src/instructions/reference/database.md +132 -0
  120. package/.framework/src/instructions/reference/design-schema.md +280 -0
  121. package/.framework/src/instructions/reference/env-vars.md +133 -0
  122. package/.framework/src/instructions/reference/frontend-sdk.md +207 -0
  123. package/.framework/src/instructions/reference/functions/account-nodes.md +75 -0
  124. package/.framework/src/instructions/reference/functions/admin-data.md +197 -0
  125. package/.framework/src/instructions/reference/functions/admin-funnel.md +90 -0
  126. package/.framework/src/instructions/reference/functions/admin-install-funnel.md +107 -0
  127. package/.framework/src/instructions/reference/functions/admin-signals.md +102 -0
  128. package/.framework/src/instructions/reference/functions/ai-agents.md +148 -0
  129. package/.framework/src/instructions/reference/functions/ai-interactions.md +156 -0
  130. package/.framework/src/instructions/reference/functions/api-keys.md +130 -0
  131. package/.framework/src/instructions/reference/functions/apps.md +140 -0
  132. package/.framework/src/instructions/reference/functions/auth.md +99 -0
  133. package/.framework/src/instructions/reference/functions/debug-auth.md +91 -0
  134. package/.framework/src/instructions/reference/functions/deliveries.md +110 -0
  135. package/.framework/src/instructions/reference/functions/embeddings.md +166 -0
  136. package/.framework/src/instructions/reference/functions/eval-harness.md +149 -0
  137. package/.framework/src/instructions/reference/functions/index.md +103 -0
  138. package/.framework/src/instructions/reference/functions/integration-outbound.md +200 -0
  139. package/.framework/src/instructions/reference/functions/integration-routes.md +151 -0
  140. package/.framework/src/instructions/reference/functions/integrations.md +130 -0
  141. package/.framework/src/instructions/reference/functions/invites.md +182 -0
  142. package/.framework/src/instructions/reference/functions/item-progress.md +107 -0
  143. package/.framework/src/instructions/reference/functions/kb.md +166 -0
  144. package/.framework/src/instructions/reference/functions/logs.md +141 -0
  145. package/.framework/src/instructions/reference/functions/observability.md +105 -0
  146. package/.framework/src/instructions/reference/functions/pipeline-executions.md +132 -0
  147. package/.framework/src/instructions/reference/functions/pipeline-runner-background.md +121 -0
  148. package/.framework/src/instructions/reference/functions/pipelines.md +136 -0
  149. package/.framework/src/instructions/reference/functions/prompt-configs.md +121 -0
  150. package/.framework/src/instructions/reference/functions/roles.md +121 -0
  151. package/.framework/src/instructions/reference/functions/security.md +140 -0
  152. package/.framework/src/instructions/reference/functions/system-cron.md +136 -0
  153. package/.framework/src/instructions/reference/functions/system.md +106 -0
  154. package/.framework/src/instructions/reference/functions/tests.md +97 -0
  155. package/.framework/src/instructions/reference/functions/timers.md +117 -0
  156. package/.framework/src/instructions/reference/functions/trigger-scheduler.md +102 -0
  157. package/.framework/src/instructions/reference/functions/triggers.md +140 -0
  158. package/.framework/src/instructions/reference/functions/types.md +146 -0
  159. package/.framework/src/instructions/reference/seeds.md +126 -0
  160. package/.framework/src/instructions/reference/shared-modules.md +127 -0
  161. package/.framework/src/instructions/reference/spine-config.md +114 -0
  162. package/.framework/src/instructions/roles.md +80 -0
  163. package/.framework/src/instructions/runtime-collaboration.md +106 -0
  164. package/.framework/src/instructions/runtime-detail.md +70 -0
  165. package/.framework/src/instructions/runtime-list.md +77 -0
  166. package/.framework/src/instructions/security.md +67 -0
  167. package/.framework/src/instructions/tasks/add-a-pipeline.md +110 -0
  168. package/.framework/src/instructions/tasks/add-a-role.md +96 -0
  169. package/.framework/src/instructions/tasks/add-a-timer.md +114 -0
  170. package/.framework/src/instructions/tasks/add-a-trigger.md +106 -0
  171. package/.framework/src/instructions/tasks/add-a-type.md +151 -0
  172. package/.framework/src/instructions/tasks/add-a-webhook.md +108 -0
  173. package/.framework/src/instructions/tasks/add-an-ai-agent.md +108 -0
  174. package/.framework/src/instructions/tasks/add-an-integration.md +124 -0
  175. package/.framework/src/instructions/tasks/build-a-custom-page.md +118 -0
  176. package/.framework/src/instructions/tasks/document-your-app.md +117 -0
  177. package/.framework/src/instructions/tasks/package-and-install-an-app.md +136 -0
  178. package/.framework/src/instructions/tasks/register-an-app.md +137 -0
  179. package/.framework/src/instructions/tasks/test-your-code.md +108 -0
  180. package/.framework/src/instructions/tasks/write-a-function.md +132 -0
  181. package/.framework/src/instructions/tasks/write-a-migration.md +110 -0
  182. package/.framework/src/instructions/testing.md +59 -0
  183. package/.framework/src/instructions/timers.md +84 -0
  184. package/.framework/src/instructions/triggers.md +69 -0
  185. package/.framework/src/instructions/types.md +93 -0
  186. package/.framework/src/lib/app-mount.ts +88 -0
  187. package/.framework/src/pages/NotFoundPage.tsx +62 -31
  188. package/.framework/src/pages/admin/AIAgentDetailPage.tsx +117 -106
  189. package/.framework/src/pages/admin/AIAgentsPage.tsx +86 -48
  190. package/.framework/src/pages/admin/APIKeyDetailPage.tsx +153 -152
  191. package/.framework/src/pages/admin/APIKeysPage.tsx +91 -90
  192. package/.framework/src/pages/admin/AlertsConfigPage.tsx +29 -18
  193. package/.framework/src/pages/admin/AppDetailPage.tsx +6 -60
  194. package/.framework/src/pages/admin/AppsPage.tsx +104 -66
  195. package/.framework/src/pages/admin/DeliveriesPage.tsx +5 -5
  196. package/.framework/src/pages/admin/EmbeddingDetailPage.tsx +5 -23
  197. package/.framework/src/pages/admin/EmbeddingsPage.tsx +5 -26
  198. package/.framework/src/pages/admin/IntegrationDetailPage.tsx +7 -7
  199. package/.framework/src/pages/admin/IntegrationsPage.tsx +85 -43
  200. package/.framework/src/pages/admin/LogsPage.tsx +144 -76
  201. package/.framework/src/pages/admin/ObservabilityDashboard.tsx +223 -140
  202. package/.framework/src/pages/admin/PipelineDetailPage.tsx +134 -113
  203. package/.framework/src/pages/admin/PipelineExecutionsPage.tsx +108 -45
  204. package/.framework/src/pages/admin/PipelinesPage.tsx +160 -115
  205. package/.framework/src/pages/admin/PromptConfigDetailPage.tsx +96 -98
  206. package/.framework/src/pages/admin/PromptConfigsPage.tsx +101 -59
  207. package/.framework/src/pages/admin/RoleDetailPage.tsx +90 -79
  208. package/.framework/src/pages/admin/RolesPage.tsx +86 -43
  209. package/.framework/src/pages/admin/SecurityPage.tsx +1 -1
  210. package/.framework/src/pages/admin/TestingDashboard.tsx +16 -28
  211. package/.framework/src/pages/admin/TimerDetailPage.tsx +117 -100
  212. package/.framework/src/pages/admin/TimersPage.tsx +90 -62
  213. package/.framework/src/pages/admin/TriggerDetailPage.tsx +90 -83
  214. package/.framework/src/pages/admin/TriggersPage.tsx +124 -99
  215. package/.framework/src/pages/admin/TypeDetailPage.tsx +152 -138
  216. package/.framework/src/pages/admin/TypesPage.tsx +90 -48
  217. package/.framework/src/pages/admin/cil/CILAgentPage.tsx +17 -25
  218. package/.framework/src/pages/admin/cil/CILChunkDetailPage.tsx +17 -27
  219. package/.framework/src/pages/admin/cil/CILDashboardPage.tsx +72 -40
  220. package/.framework/src/pages/admin/cil/CILFileListPage.tsx +321 -129
  221. package/.framework/src/pages/admin/cil/CILFileSelectPage.tsx +18 -29
  222. package/.framework/src/pages/admin/cil/CILGraphPage.tsx +26 -38
  223. package/.framework/src/pages/admin/cil/CILIngestionPage.tsx +34 -46
  224. package/.framework/src/pages/admin/cil/CILProjectsPage.tsx +189 -103
  225. package/.framework/src/pages/admin/cil/CILSearchPage.tsx +246 -136
  226. package/.framework/src/pages/admin/cil/CILSuggestionsPage.tsx +11 -22
  227. package/.framework/src/pages/admin/cil/CILVersionsPage.tsx +9 -20
  228. package/.framework/src/pages/admin/cil/FlexiblePipelinePage.tsx +26 -38
  229. package/.framework/src/pages/admin/kb/KBAdminPage.tsx +7 -26
  230. package/.framework/src/pages/auth/LoginPage.tsx +3 -2
  231. package/.framework/src/pages/auth/RegisterPage.tsx +16 -8
  232. package/.framework/templates/agent/AGENTS.md +167 -0
  233. package/.framework/templates/agent/skills/spine-add-ai-agent/SKILL.md +58 -0
  234. package/.framework/templates/agent/skills/spine-add-automation/SKILL.md +62 -0
  235. package/.framework/templates/agent/skills/spine-add-integration/SKILL.md +63 -0
  236. package/.framework/templates/agent/skills/spine-architect/SKILL.md +86 -0
  237. package/.framework/templates/agent/skills/spine-install-app/SKILL.md +79 -0
  238. package/.framework/templates/agent/skills/spine-migration/SKILL.md +75 -0
  239. package/.framework/templates/agent/skills/spine-new-app/SKILL.md +79 -0
  240. package/.framework/templates/agent/skills/spine-new-function/SKILL.md +71 -0
  241. package/.framework/templates/agent/skills/spine-new-type/SKILL.md +72 -0
  242. package/.framework/templates/agent/skills/spine-schema/SKILL.md +77 -0
  243. package/.framework/templates/agent/skills/spine-test/SKILL.md +67 -0
  244. package/.framework/templates/agent/skills/spine-troubleshoot/SKILL.md +74 -0
  245. package/.framework/templates/agent/skills/spine-upgrade/SKILL.md +69 -0
  246. package/.framework/templates/project.json +4 -1
  247. package/.framework/tests/unit/account-scoping-gates.test.ts +394 -0
  248. package/.framework/tests/unit/agent-files.test.ts +355 -0
  249. package/.framework/tests/unit/agent-runner.test.ts +479 -44
  250. package/.framework/tests/unit/api-keys-create-scope-gate.test.ts +160 -0
  251. package/.framework/tests/unit/api-keys-omit-secret-fields.test.ts +38 -0
  252. package/.framework/tests/unit/app-mount.test.ts +80 -0
  253. package/.framework/tests/unit/bootstrap.test.ts +242 -0
  254. package/.framework/tests/unit/cli-context-api-key.test.ts +114 -0
  255. package/.framework/tests/unit/debug-auth.test.ts +38 -0
  256. package/.framework/tests/unit/deliveries-account-scoping.test.ts +185 -0
  257. package/.framework/tests/unit/integration-outbound-credentials.test.ts +167 -0
  258. package/.framework/tests/unit/integrations-audit-redaction.test.ts +130 -0
  259. package/.framework/tests/unit/logging-app-id.test.ts +75 -0
  260. package/.framework/tests/unit/security-definer-grants.test.ts +154 -0
  261. package/.framework/tests/unit/system-context-denial.test.ts +145 -0
  262. package/.framework/tests/unit/system-cron.test.ts +240 -0
  263. package/.framework/tests/unit/timers.test.ts +159 -0
  264. package/README.md +125 -166
  265. package/config/tsconfig.cli.json +2 -2
  266. package/package.json +15 -4
  267. package/templates/project/package-lock.json +2 -2
  268. package/.framework/docs/admin-routes.md +0 -76
  269. package/.framework/docs/api-docs-progress.md +0 -38
  270. package/.framework/docs/api-governance.md +0 -146
  271. package/.framework/docs/api-testing-results.md +0 -212
  272. package/.framework/docs/assembly-launch-guide.md +0 -138
  273. package/.framework/docs/audit-results.md +0 -590
  274. package/.framework/docs/db-api-inventory.md +0 -95
  275. package/.framework/docs/gap-remediation-backlog.md +0 -103
  276. package/.framework/docs/ui-adoption-verification.md +0 -111
  277. package/.framework/docs/ui-api-coverage.md +0 -84
  278. package/.framework/docs/v2-compatibility-audit.md +0 -228
  279. package/.framework/mcp/index.ts +0 -133
  280. package/.framework/mcp/load-env.ts +0 -60
  281. package/.framework/mcp/shared/app-manifest.ts +0 -275
  282. package/.framework/mcp/shared/db.ts +0 -477
  283. package/.framework/mcp/shared/kb.ts +0 -118
  284. package/.framework/mcp/tools/architect.ts +0 -431
  285. package/.framework/mcp/tools/cil/context.ts +0 -345
  286. package/.framework/mcp/tools/cil/graph.ts +0 -242
  287. package/.framework/mcp/tools/cil/ingest.ts +0 -1217
  288. package/.framework/mcp/tools/cil/pipeline-orchestrator.ts +0 -693
  289. package/.framework/mcp/tools/cil/pipeline.ts +0 -767
  290. package/.framework/mcp/tools/cil/project.ts +0 -791
  291. package/.framework/mcp/tools/cil/retrieval.ts +0 -336
  292. package/.framework/mcp/tools/cil/search-core.ts +0 -454
  293. package/.framework/mcp/tools/cil/search.ts +0 -97
  294. package/.framework/mcp/tools/cil/suggest.ts +0 -186
  295. package/.framework/mcp/tools/cil/validate.ts +0 -1369
  296. package/.framework/mcp/tools/kb/delete.ts +0 -139
  297. package/.framework/mcp/tools/kb/index.ts +0 -52
  298. package/.framework/mcp/tools/kb/ingest.ts +0 -84
  299. package/.framework/mcp/tools/kb/list-types.ts +0 -102
  300. package/.framework/mcp/tools/kb/publish.ts +0 -100
  301. package/.framework/mcp/tools/kb/reindex.ts +0 -86
  302. package/.framework/mcp/tools/kb/revoke.ts +0 -85
  303. package/.framework/mcp/tools/kb/search.ts +0 -101
  304. package/.framework/mcp/tools/kb/upsert.ts +0 -125
  305. package/.framework/mcp/tools/observability.ts +0 -510
@@ -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.
@@ -0,0 +1,96 @@
1
+ ---
2
+ title: Integrations
3
+ audience: both
4
+ kind: entity
5
+ verified_against: e13127d
6
+ verified_on: 2026-10-30
7
+ source_files:
8
+ - .framework/functions/integrations.ts
9
+ - .framework/functions/integration-outbound.ts
10
+ - .framework/functions/integration-routes.ts
11
+ - .framework/functions/_shared/resolve-credentials.ts
12
+ - .framework/src/pages/admin/IntegrationsPage.tsx
13
+ - .framework/src/pages/admin/IntegrationDetailPage.tsx
14
+ ---
15
+
16
+ ## What this is for
17
+
18
+ An **integration** connects Spine to an external service (OpenAI, Resend, a generic HTTP endpoint, a database, ...). The record stores the provider, runtime `config` (including which adapter handles calls), and `credentials`. Pipelines and app code reference the integration by slug.
19
+
20
+ ## Fields and settings
21
+
22
+ - **Name** *(required)* — display name. The slug is **derived from it** server-side (`OpenAI` → `openai`); pass `slug` in the body only to override.
23
+ - **Type** *(required)* — select: `webhook`, `api`, `database`, `file`, `custom`. Categorizes the integration; the create form pre-fills sensible `config`/`credentials` templates per type.
24
+ - **Provider** *(required)* — free-text provider name (e.g. `openai`, `resend`, `postgres`).
25
+ - **Version** — string, default `1.0.0`.
26
+ - **Config (JSON)** — adapter and runtime settings. The adapter is named **here**, not as a top-level field: `config.outbound_adapter` (or `config.inbound_adapter` for inbound webhooks) points at an adapter module such as `adapters/openai-outbound`.
27
+ - **Credentials (JSON)** — secrets keyed by field name, each `{ "source": "env_var" | "value", "value": "..." }`. `source: "env_var"` resolves the named env var inside the function runtime; `source: "value"` stores the literal secret in the DB. The credential field callers read defaults to `api_token`.
28
+ - **Configured** — computed, read-only. `is_configured` is re-derived on every save from `credentials` (all entries must resolve); the UI shows it as Configured/Pending.
29
+ - **App ID** — select, optional. Owning app; blank = account-scoped.
30
+ - **Active** — boolean. Inactive integrations fail closed — callers get an error, not a fallback.
31
+ - **Description / Metadata** — optional notes and free-form data.
32
+
33
+ **Downstream effects**
34
+
35
+ - `env_var` credentials are resolved inside the function runtime — the variable must exist in the deployed env or calls fail at request time (`credential_env_missing`), not at save time. `source: "value"` persists the literal secret — prefer `env_var` for anything real.
36
+ - An absent or explicitly-empty (`source: "value"`, `value: ""`) credential entry means "call without auth" — the outbound broker sends no credential and the adapter decides whether one is required (the seeded `generic-http` integration works unauthenticated out of the box this way).
37
+ - Built-in outbound adapters: `adapters/openai-outbound`, `adapters/generic-webhook-outbound`, `adapters/resend-outbound`. Any other adapter path is dynamically imported — a typo saves fine but fails on first call.
38
+ - Outbound calls create a `webhook_deliveries` row (`pending`, `max_attempts` default 3 or `config.retry_policy.max_attempts`) and show up under Deliveries.
39
+ - Apps declare `integration_deps`; installing an app without its integrations leaves features broken until the records exist.
40
+ - The list/detail APIs use `adminDb` for system admins — integrations exist per account and per system scope.
41
+
42
+ ## Minimal configuration
43
+
44
+ ```json
45
+ {
46
+ "name": "OpenAI",
47
+ "integration_type": "api",
48
+ "provider": "openai",
49
+ "is_active": true,
50
+ "config": {
51
+ "outbound_adapter": "adapters/openai-outbound",
52
+ "model": "gpt-4o"
53
+ },
54
+ "credentials": { "api_token": { "source": "env_var", "value": "OPENAI_API_KEY" } }
55
+ }
56
+ ```
57
+
58
+ ## Full configuration
59
+
60
+ ```json
61
+ {
62
+ "name": "Outbound webhook",
63
+ "integration_type": "api",
64
+ "provider": "custom",
65
+ "version": "1.2.0",
66
+ "is_active": true,
67
+ "config": {
68
+ "outbound_adapter": "adapters/generic-webhook-outbound",
69
+ "base_url": "https://hooks.example.com",
70
+ "timeout_ms": 10000,
71
+ "retry_policy": { "max_attempts": 5 }
72
+ },
73
+ "credentials": { "api_token": { "source": "env_var", "value": "ACME_HOOK_TOKEN" } },
74
+ "metadata": { "owner": "platform" }
75
+ }
76
+ ```
77
+
78
+ ## Example
79
+
80
+ A support app lists `integration_deps: ["openai"]` — the AI agents resolve the `openai` integration by slug for model calls (credential field `api_token`), and a second integration (`config.outbound_adapter: "adapters/generic-webhook-outbound"`) delivers outbound ticket events, each attempt logged under Deliveries.
81
+
82
+ ## Core files
83
+
84
+ - `.framework/functions/integrations.ts` — API (list/get/create/update; `is_configured` computed on write; non-admin reads are sanitized)
85
+ - `.framework/functions/integration-outbound.ts` — outbound broker (adapter registry, delivery rows, retry math)
86
+ - `.framework/functions/integration-routes.ts` — inbound webhook entry
87
+ - `.framework/functions/_shared/resolve-credentials.ts` — `env_var`/`value` credential resolution
88
+ - `.framework/src/pages/admin/IntegrationsPage.tsx` / `IntegrationDetailPage.tsx` — admin UI (per-type config templates on the detail form)
89
+ - Table: `public.integrations`
90
+
91
+ ## Agent notes
92
+
93
+ - Credentials shape is `{ "api_token": { "source": "env_var", "value": "OPENAI_API_KEY" } }` — nested `source`/`value` objects, not `{ "env_var": "..." }`. The latter saves but never resolves.
94
+ - Never put real secrets in `credentials.*.value` with `source: "value"` in seeds or docs — always `env_var`.
95
+ - There is no top-level `adapter` or `configuration` column — the field is `config`, and the adapter lives at `config.outbound_adapter` / `config.inbound_adapter`.
96
+ - After changing credentials, the broker picks them up on the next call — no cache flush needed.
@@ -0,0 +1,83 @@
1
+ ---
2
+ title: "CIL markers and generated doc tags"
3
+ audience: developers, agents
4
+ kind: reference
5
+ verified_against: f69c37d
6
+ verified_on: 2026-10-29
7
+ source_files:
8
+ - .framework/functions/_shared/pipeline-runner.ts
9
+ - .framework/scripts/cil-migrate-markers.ts
10
+ - AGENTS.md
11
+ ---
12
+
13
+ # CIL markers and generated doc tags
14
+
15
+ Files throughout `.framework/` — `src`, `functions`, `cli`, `migrations` —
16
+ carry dense comment blocks that look like this:
17
+
18
+ ```ts
19
+ // CIL[BEGIN stable_id="~/.framework/functions/_shared/pipeline-runner.ts:isuuid:function" type="function" identity="isUuid" parent="~/.framework/functions/_shared/pipeline-runner.ts"]
20
+ // CIL[DOC-MACRO purpose="isUuid function"]
21
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
22
+ function isUuid(v: string | undefined | null): v is string { ... }
23
+ // CIL[END stable_id="~/.framework/functions/_shared/pipeline-runner.ts:isuuid:function"]
24
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
25
+ ```
26
+
27
+ and generated JSDoc like this:
28
+
29
+ ```ts
30
+ /**
31
+ * Validates whether a given string is a properly formatted UUID.
32
+ * @inputSpec - v: string — the value to be checked
33
+ * @outputSpec v is string — true if the value is a valid UUID
34
+ * @sideEffects none
35
+ * @stability stable
36
+ * @calls UUID_RE.test
37
+ * @cil-generated
38
+ */
39
+ ```
40
+
41
+ ## What they are
42
+
43
+ **CIL** (Code Intelligence Layer) is the repository's internal
44
+ code-indexing tooling — it chunks the codebase into addressable units,
45
+ attaches generated documentation, and keeps embeddings in sync for semantic
46
+ search inside the monorepo. The comments are its on-disk metadata:
47
+
48
+ - `// CIL[BEGIN ...]` / `// CIL[END ...]` — delimit one tracked code chunk.
49
+ `stable_id` is the chunk's durable identity
50
+ (`<file>:<slug>:<kind>`); `type`, `identity`, and `parent` describe it.
51
+ - `// CIL[DOC-* …]` — generated or curated facts about the chunk:
52
+ `DOC-MACRO` (purpose), `DOC-RESPONSIBILITY`, `DOC-CONTEXT`
53
+ (module/layer/related files), `DOC-CONTRACT` (inputs/outputs/errors/
54
+ side_effects), `DOC-MICRO` (logic summary, notable decisions),
55
+ `DOC-CONFIDENCE` (pass + score), `DOC-STABILITY`, `DOC-AUDIENCE`,
56
+ `DOC-PARAM`, `DOC-NOTE`, and `DOC-LEARNING`.
57
+ - `// CIL[DOC-VECTOR type="…" content="…" status="…"]` — the payload that
58
+ becomes a search embedding (types include `context`, `blast_radius`,
59
+ `constraint`, `configuration`, `implementation_pattern`, `user_journey`).
60
+ `status="ready"` means it was generated; **`status="pending_human_input"`
61
+ means the field is intentionally blank until an author fills it** — it is
62
+ not an error and not a warning about the code itself.
63
+ - JSDoc tags `@macro`, `@micro`, `@inputSpec`, `@outputSpec`, `@sideEffects`,
64
+ `@calls`, `@seeAlso`, `@errorHandling`, `@stability`, `@module`, `@layer`,
65
+ `@audience`, `@cil-generated` mirror the same metadata in human-readable
66
+ form; `@cil-generated` marks text written by the pipeline rather than a
67
+ person.
68
+
69
+ ## What they mean for you
70
+
71
+ - **Safe to ignore.** They are comments; they have no runtime effect, no API
72
+ surface, and no effect on how you build apps on Spine. CIL is maintainer
73
+ tooling, not a framework feature.
74
+ - **Read them as hints, not truth.** `DOC-*` summaries and JSDoc are
75
+ generated interpretation — usually accurate, occasionally stale. The code
76
+ is the authority; treat the tags like any other doc comment.
77
+ - **In framework files, leave them in place.** Editing or deleting markers by
78
+ hand is harmless locally but gets rebuilt/renumbered the next time the
79
+ repo's marker tooling runs (see `cil:migrate-markers` /
80
+ `.framework/scripts/cil-migrate-markers.ts`). In your own `custom/` code
81
+ you're free to add or omit them — nothing requires them.
82
+ - The contributor-facing conventions live in the repo's `AGENTS.md`; this
83
+ page is only the legend for readers who meet the markers in shipped source.