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,3 +1,4 @@
1
+ // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:create:constant" type="constant" identity="create" parent="~/.framework/functions/embeddings.ts"]
1
2
  /**
2
3
  * Creates a new embedding record for a knowledge base item and persists it to the database. This function also handles ownership and audit logging for the embedding.
3
4
  *
@@ -7,7 +8,6 @@
7
8
  * @calls ctx.db.from, emitLog
8
9
  * @cil-generated
9
10
  */
10
- // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:create:constant" type="constant" identity="create" parent="~/.framework/functions/embeddings.ts"]
11
11
  export const create = createHandler(async (ctx, body) => {
12
12
  const { model_id, document_id, chunk_index, content, metadata } = body
13
13
  if (!model_id || !document_id || !content) {
@@ -36,6 +36,7 @@ export const create = createHandler(async (ctx, body) => {
36
36
  return data
37
37
  })
38
38
  // CIL[END stable_id="~/.framework/functions/embeddings.ts:create:constant"]
39
+ // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:update:constant" type="constant" identity="update" parent="~/.framework/functions/embeddings.ts"]
39
40
  /**
40
41
  * Updates an existing embedding's content and metadata, applying partial updates to an embedding record. It also emits an audit log for tracking changes.
41
42
  *
@@ -45,7 +46,6 @@ export const create = createHandler(async (ctx, body) => {
45
46
  * @calls ctx.db.from('embeddings'), emitLog
46
47
  * @cil-generated
47
48
  */
48
- // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:update:constant" type="constant" identity="update" parent="~/.framework/functions/embeddings.ts"]
49
49
  export const update = createHandler(async (ctx, body) => {
50
50
  const id = body?.id || ctx.query?.id
51
51
  const { id: _bodyId, content, metadata } = body || {}
@@ -55,12 +55,15 @@ export const update = createHandler(async (ctx, body) => {
55
55
  const updateFields: Record<string, any> = {}
56
56
  if (content !== undefined) updateFields.content = content
57
57
  if (metadata !== undefined) updateFields.metadata = metadata
58
- const { data, error: err } = await ctx.db
58
+ let query = ctx.db
59
59
  .from('embeddings')
60
60
  .update(updateFields)
61
61
  .eq('id', id)
62
- .select()
63
- .single()
62
+ if (!isSystemPrincipal(ctx)) {
63
+ if (!ctx.accountId) throw new Error('Account context required')
64
+ query = query.eq('account_id', ctx.accountId)
65
+ }
66
+ const { data, error: err } = await query.select().single()
64
67
  if (err) throw err
65
68
  await emitLog(ctx, 'embedding.updated',
66
69
  { type: 'embedding', id },
@@ -78,13 +81,14 @@ export const update = createHandler(async (ctx, body) => {
78
81
  */
79
82
  // chunk_index is unique per (model_id, document_id) — each vector type
80
83
  // occupies a fixed slot (matching the CIL pipeline's convention).
81
- // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:vector_type_slots:constant" type="constant" identity="VECTOR_TYPE_SLOTS" parent="~/.framework/functions/embeddings.ts"]
84
+ // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:VECTOR_TYPE_SLOTS:constant" type="constant" identity="VECTOR_TYPE_SLOTS" parent="~/.framework/functions/embeddings.ts"]
82
85
  const VECTOR_TYPE_SLOTS: Record<string, number> = {
83
86
  semantic: 0, structure: 1, context: 2, blast_radius: 3,
84
87
  configuration: 4, constraint: 5, summary: 6, intent: 7,
85
88
  cause: 8, procedure: 9, outcome: 10, error_signal: 11,
86
89
  }
87
- // CIL[END stable_id="~/.framework/functions/embeddings.ts:vector_type_slots:constant"]
90
+ // CIL[END stable_id="~/.framework/functions/embeddings.ts:VECTOR_TYPE_SLOTS:constant"]
91
+ // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:generate:constant" type="constant" identity="generate" parent="~/.framework/functions/embeddings.ts"]
88
92
  /**
89
93
  * Generates or refreshes vector embeddings for a knowledge base item. This function builds text content for configured vector types, calls an embedding API, and persists vectors with hashes.
90
94
  *
@@ -94,16 +98,26 @@ const VECTOR_TYPE_SLOTS: Record<string, number> = {
94
98
  * @calls adminDb.from('items'), adminDb.select, adminDb.eq, adminDb.single
95
99
  * @cil-generated
96
100
  */
97
- // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:generate:constant" type="constant" identity="generate" parent="~/.framework/functions/embeddings.ts"]
98
101
  export const generate = createHandler(async (ctx, body) => {
99
102
  const { item_id, force_regenerate = false, account_id_override } = body || {}
100
103
  if (!item_id) throw new Error('item_id is required')
104
+ const isSystem = isSystemPrincipal(ctx)
105
+ if (!isSystem && !ctx.accountId) {
106
+ throw new Error('Account context required')
107
+ }
101
108
  const { data: item, error: itemErr } = await adminDb
102
109
  .from('items')
103
110
  .select('*, type:types(slug, design_schema)')
104
111
  .eq('id', item_id)
105
112
  .single()
106
113
  if (itemErr || !item) throw new Error(`Item ${item_id} not found`)
114
+ // The adminDb read above bypasses RLS — a scoped caller may only generate
115
+ // vectors for items inside its own account.
116
+ if (!isSystem && item.account_id && item.account_id !== ctx.accountId) {
117
+ const e: any = new Error('Insufficient permissions to generate embeddings for this item')
118
+ e.statusCode = 403
119
+ throw e
120
+ }
107
121
  const typeDesign = item.type?.design_schema || {}
108
122
  const typeSlug = item.type?.slug || ''
109
123
  // Match the kbIngest convention (metadata.item_type = type slug) so retrieval
@@ -120,7 +134,12 @@ export const generate = createHandler(async (ctx, body) => {
120
134
  vectorTypes = ['semantic', 'structure']
121
135
  }
122
136
  const embeddingFields: string[] = typeDesign.embedding_fields?.structure || []
123
- const resolvedAccountId = account_id_override || item.account_id || await getPlatformAccountId()
137
+ // account_id_override is a cross-account write primitive — honor it only
138
+ // for system-level callers. Scoped principals always write vectors under
139
+ // their own account.
140
+ const resolvedAccountId = isSystem
141
+ ? (account_id_override || item.account_id || await getPlatformAccountId())
142
+ : ctx.accountId
124
143
  const isPublished = item.status === 'published'
125
144
  const { data: existing } = await adminDb
126
145
  .from('embeddings')
@@ -236,7 +255,6 @@ export const generate = createHandler(async (ctx, body) => {
236
255
  *
237
256
  * @cil-generated
238
257
  */
239
- // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/functions/embeddings.ts"]
240
258
  // CIL[DOC-MACRO purpose="Creates a new embedding record for a knowledge base item."]
241
259
  // CIL[DOC-RESPONSIBILITY responsibility="Persists an embedding to the embeddings table with ownership and audit logging."]
242
260
  // CIL[DOC-CONTEXT module="embeddings" layer="functions" related_files=".framework/functions/_shared/audit.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/llm.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/permissions.ts,.framework/functions/_shared/principal.ts,.framework/functions/embeddings.ts"]
@@ -430,6 +448,7 @@ export const generate = createHandler(async (ctx, body) => {
430
448
  // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
431
449
  // CIL[DOC-STABILITY stability="stable"]
432
450
  // CIL[DOC-AUDIENCE audience="developers, operators"]
451
+ // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/functions/embeddings.ts"]
433
452
  import { createHash } from 'crypto'
434
453
  import { createHandler } from './_shared/middleware'
435
454
  import { adminDb } from './_shared/db'
@@ -438,6 +457,17 @@ import { isSystemAdmin } from './_shared/principal'
438
457
  import { sanitizeRecordData } from './_shared/permissions'
439
458
  import { callOpenAIEmbeddings, callOpenAIChat } from './_shared/llm'
440
459
  // CIL[END stable_id="~/.framework/functions/embeddings.ts:module_header:module_header"]
460
+
461
+ // True only for platform-level principals: a system_admin role or an
462
+ // internal machine principal with no account binding (SYSTEM_PRINCIPAL,
463
+ // produced only by the INTERNAL_INVOKE_SECRET path). Machine principals
464
+ // resolve to the service-role adminDb via getPrincipalDb, so account-bound
465
+ // API keys must be scoped to their own account below.
466
+ // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:isSystemPrincipal:function" type="function" identity="isSystemPrincipal" parent="~/.framework/functions/embeddings.ts"]
467
+ function isSystemPrincipal(ctx: any): boolean {
468
+ return isSystemAdmin(ctx.principal) || (ctx.principal?.isInternal === true && !ctx.accountId)
469
+ }
470
+ // CIL[END stable_id="~/.framework/functions/embeddings.ts:isSystemPrincipal:function"]
441
471
  // CIL[DOC-VECTOR type="context" content="purpose='Imports shared utilities for the embeddings Netlify function.'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/audit.ts"]
442
472
  // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
443
473
  // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
@@ -454,7 +484,6 @@ import { callOpenAIEmbeddings, callOpenAIChat } from './_shared/llm'
454
484
  * @stability stable
455
485
  * @cil-generated
456
486
  */
457
- // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:striphtml:function" type="function" identity="stripHtml" parent="~/.framework/functions/embeddings.ts"]
458
487
  // CIL[DOC-MACRO purpose="Strips HTML tags and decodes common HTML entities."]
459
488
  // CIL[DOC-RESPONSIBILITY responsibility="Normalizes HTML content into plain text for embedding."]
460
489
  // CIL[DOC-CONTEXT module="embeddings" layer="functions" related_files=".framework/functions/_shared/audit.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/llm.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/permissions.ts,.framework/functions/_shared/principal.ts,.framework/functions/embeddings.ts"]
@@ -463,6 +492,7 @@ import { callOpenAIEmbeddings, callOpenAIChat } from './_shared/llm'
463
492
  // CIL[DOC-MICRO logic_summary="Replaces tags, decodes entities, collapses whitespace, and trims the string." notable_decisions="none"]
464
493
  // CIL[DOC-STABILITY stability="stable"]
465
494
  // CIL[DOC-AUDIENCE audience="developers"]
495
+ // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:stripHtml:function" type="function" identity="stripHtml" parent="~/.framework/functions/embeddings.ts"]
466
496
  function stripHtml(html: string): string {
467
497
  return html
468
498
  .replace(/<[^>]+>/g, ' ')
@@ -470,7 +500,7 @@ function stripHtml(html: string): string {
470
500
  .replace(/&quot;/g, '"').replace(/&#39;/g, "'").replace(/&nbsp;/g, ' ')
471
501
  .replace(/\s+/g, ' ').trim()
472
502
  }
473
- // CIL[END stable_id="~/.framework/functions/embeddings.ts:striphtml:function"]
503
+ // CIL[END stable_id="~/.framework/functions/embeddings.ts:stripHtml:function"]
474
504
 
475
505
  // CIL[DOC-VECTOR type="context" content="purpose='Strips HTML tags and decodes common HTML entities.'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/audit.ts"]
476
506
  // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
@@ -488,7 +518,6 @@ function stripHtml(html: string): string {
488
518
  * @stability stable
489
519
  * @cil-generated
490
520
  */
491
- // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:firstnonempty:function" type="function" identity="firstNonEmpty" parent="~/.framework/functions/embeddings.ts"]
492
521
  // CIL[DOC-MACRO purpose="Returns the first non-empty string from a list of values."]
493
522
  // CIL[DOC-RESPONSIBILITY responsibility="Selects the first truthy, trimmed string from candidates."]
494
523
  // CIL[DOC-CONTEXT module="embeddings" layer="functions" related_files=".framework/functions/_shared/audit.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/llm.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/permissions.ts,.framework/functions/_shared/principal.ts,.framework/functions/embeddings.ts"]
@@ -497,13 +526,14 @@ function stripHtml(html: string): string {
497
526
  // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
498
527
  // CIL[DOC-STABILITY stability="stable"]
499
528
  // CIL[DOC-AUDIENCE audience="developers"]
529
+ // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:firstNonEmpty:function" type="function" identity="firstNonEmpty" parent="~/.framework/functions/embeddings.ts"]
500
530
  function firstNonEmpty(...values: (string | undefined | null)[]): string {
501
531
  for (const v of values) {
502
532
  if (v && String(v).trim()) return String(v).trim()
503
533
  }
504
534
  return ''
505
535
  }
506
- // CIL[END stable_id="~/.framework/functions/embeddings.ts:firstnonempty:function"]
536
+ // CIL[END stable_id="~/.framework/functions/embeddings.ts:firstNonEmpty:function"]
507
537
  // CIL[DOC-VECTOR type="context" content="purpose='Returns the first non-empty string from a list of values.'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/audit.ts"]
508
538
  // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
509
539
  // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
@@ -522,7 +552,6 @@ function firstNonEmpty(...values: (string | undefined | null)[]): string {
522
552
  * @calls stripHtml
523
553
  * @cil-generated
524
554
  */
525
- // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:buildsemanticcontent:function" type="function" identity="buildSemanticContent" parent="~/.framework/functions/embeddings.ts"]
526
555
  // CIL[DOC-MACRO purpose="Builds the semantic text content for an item embedding."]
527
556
  // CIL[DOC-LEARNING topic="retrieval" content="KB articles store their body in data.content (data.body/markdown for other kinds) while description is only a short blurb — embedding title+description alone produced useless vectors."]
528
557
  // CIL[DOC-RESPONSIBILITY responsibility="Concatenates the item title, description blurb, and data-level body for vector search."]
@@ -532,6 +561,7 @@ function firstNonEmpty(...values: (string | undefined | null)[]): string {
532
561
  // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
533
562
  // CIL[DOC-STABILITY stability="stable"]
534
563
  // CIL[DOC-AUDIENCE audience="developers"]
564
+ // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:buildSemanticContent:function" type="function" identity="buildSemanticContent" parent="~/.framework/functions/embeddings.ts"]
535
565
  function buildSemanticContent(item: any): string {
536
566
  const title = item.title || ''
537
567
  const blurb = stripHtml(item.description || '')
@@ -540,7 +570,7 @@ function buildSemanticContent(item: any): string {
540
570
  )
541
571
  return [title, blurb, body].filter(Boolean).join('\n')
542
572
  }
543
- // CIL[END stable_id="~/.framework/functions/embeddings.ts:buildsemanticcontent:function"]
573
+ // CIL[END stable_id="~/.framework/functions/embeddings.ts:buildSemanticContent:function"]
544
574
  // CIL[DOC-VECTOR type="context" content="purpose='Builds the semantic text content for an item embedding.'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/audit.ts"]
545
575
  // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
546
576
  // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
@@ -559,7 +589,6 @@ function buildSemanticContent(item: any): string {
559
589
  * @stability stable
560
590
  * @cil-generated
561
591
  */
562
- // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:buildstructurecontent:function" type="function" identity="buildStructureContent" parent="~/.framework/functions/embeddings.ts"]
563
592
  // CIL[DOC-MACRO purpose="Builds a structured JSON representation of an item for vector indexing."]
564
593
  // CIL[DOC-RESPONSIBILITY responsibility="Serializes item fields, metadata, and configured embedding fields into JSON."]
565
594
  // CIL[DOC-CONTEXT module="embeddings" layer="functions" related_files=".framework/functions/_shared/audit.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/llm.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/permissions.ts,.framework/functions/_shared/principal.ts,.framework/functions/embeddings.ts"]
@@ -568,6 +597,7 @@ function buildSemanticContent(item: any): string {
568
597
  // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
569
598
  // CIL[DOC-STABILITY stability="stable"]
570
599
  // CIL[DOC-AUDIENCE audience="developers"]
600
+ // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:buildStructureContent:function" type="function" identity="buildStructureContent" parent="~/.framework/functions/embeddings.ts"]
571
601
  function buildStructureContent(item: any, embeddingFields: string[] = []): string {
572
602
  const base: Record<string, any> = {
573
603
  title: item.title || '',
@@ -584,7 +614,7 @@ function buildStructureContent(item: any, embeddingFields: string[] = []): strin
584
614
  }
585
615
  return JSON.stringify(base)
586
616
  }
587
- // CIL[END stable_id="~/.framework/functions/embeddings.ts:buildstructurecontent:function"]
617
+ // CIL[END stable_id="~/.framework/functions/embeddings.ts:buildStructureContent:function"]
588
618
  // CIL[DOC-VECTOR type="context" content="purpose='Builds a structured JSON representation of an item for vector indexing.'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/audit.ts"]
589
619
  // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
590
620
  // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
@@ -603,7 +633,6 @@ function buildStructureContent(item: any, embeddingFields: string[] = []): strin
603
633
  * @calls firstNonEmpty
604
634
  * @cil-generated
605
635
  */
606
- // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:buildintentcontent:function" type="function" identity="buildIntentContent" parent="~/.framework/functions/embeddings.ts"]
607
636
  // CIL[DOC-MACRO purpose="Extracts the intent text for an item embedding."]
608
637
  // CIL[DOC-STABILITY stability="internal"]
609
638
  // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
@@ -612,6 +641,7 @@ function buildStructureContent(item: any, embeddingFields: string[] = []): strin
612
641
  // CIL[DOC-CONTRACT inputs="item: any" outputs="string" errors="none" side_effects="none"]
613
642
  // CIL[DOC-MICRO logic_summary="Returns the first non-empty value among intent, learning_objectives, ca_reported_issue, use_case." notable_decisions="none"]
614
643
  // CIL[DOC-AUDIENCE audience="developers"]
644
+ // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:buildIntentContent:function" type="function" identity="buildIntentContent" parent="~/.framework/functions/embeddings.ts"]
615
645
  function buildIntentContent(item: any): string {
616
646
  return firstNonEmpty(
617
647
  item.data?.intent,
@@ -620,7 +650,7 @@ function buildIntentContent(item: any): string {
620
650
  item.data?.use_case,
621
651
  )
622
652
  }
623
- // CIL[END stable_id="~/.framework/functions/embeddings.ts:buildintentcontent:function"]
653
+ // CIL[END stable_id="~/.framework/functions/embeddings.ts:buildIntentContent:function"]
624
654
 
625
655
  /**
626
656
  * Extracts the intent text for an item embedding by retrieving the first non-empty cause-related field from the item data. This function is designed to facilitate the processing of item embeddings in the context of the application.
@@ -633,7 +663,6 @@ function buildIntentContent(item: any): string {
633
663
  * @calls firstNonEmpty
634
664
  * @cil-generated
635
665
  */
636
- // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:buildcausecontent:function" type="function" identity="buildCauseContent" parent="~/.framework/functions/embeddings.ts"]
637
666
  // CIL[DOC-VECTOR type="context" content="purpose='Extracts the intent text for an item embedding.'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/audit.ts"]
638
667
  // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
639
668
  // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
@@ -648,6 +677,7 @@ function buildIntentContent(item: any): string {
648
677
  // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
649
678
  // CIL[DOC-STABILITY stability="stable"]
650
679
  // CIL[DOC-AUDIENCE audience="developers"]
680
+ // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:buildCauseContent:function" type="function" identity="buildCauseContent" parent="~/.framework/functions/embeddings.ts"]
651
681
  function buildCauseContent(item: any): string {
652
682
  return firstNonEmpty(
653
683
  item.data?.cause,
@@ -656,7 +686,7 @@ function buildCauseContent(item: any): string {
656
686
  item.data?.root_cause,
657
687
  )
658
688
  }
659
- // CIL[END stable_id="~/.framework/functions/embeddings.ts:buildcausecontent:function"]
689
+ // CIL[END stable_id="~/.framework/functions/embeddings.ts:buildCauseContent:function"]
660
690
  // CIL[DOC-VECTOR type="context" content="purpose='Extracts the cause text for an item embedding.'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/audit.ts"]
661
691
  // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
662
692
  // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
@@ -675,7 +705,6 @@ function buildCauseContent(item: any): string {
675
705
  * @calls firstNonEmpty
676
706
  * @cil-generated
677
707
  */
678
- // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:buildprocedurecontent:function" type="function" identity="buildProcedureContent" parent="~/.framework/functions/embeddings.ts"]
679
708
  // CIL[DOC-MACRO purpose="Extracts the procedure text for an item embedding."]
680
709
  // CIL[DOC-RESPONSIBILITY responsibility="Picks the first available procedure or resolution text from item data."]
681
710
  // CIL[DOC-CONTEXT module="embeddings" layer="functions" related_files=".framework/functions/_shared/audit.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/llm.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/permissions.ts,.framework/functions/_shared/principal.ts,.framework/functions/embeddings.ts"]
@@ -684,6 +713,7 @@ function buildCauseContent(item: any): string {
684
713
  // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
685
714
  // CIL[DOC-STABILITY stability="stable"]
686
715
  // CIL[DOC-AUDIENCE audience="developers"]
716
+ // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:buildProcedureContent:function" type="function" identity="buildProcedureContent" parent="~/.framework/functions/embeddings.ts"]
687
717
  function buildProcedureContent(item: any): string {
688
718
  const steps = item.data?.procedure || item.data?.ca_solution_steps || item.data?.steps
689
719
  if (Array.isArray(steps) && steps.length) {
@@ -691,7 +721,7 @@ function buildProcedureContent(item: any): string {
691
721
  }
692
722
  return firstNonEmpty(item.data?.procedure, item.data?.resolution)
693
723
  }
694
- // CIL[END stable_id="~/.framework/functions/embeddings.ts:buildprocedurecontent:function"]
724
+ // CIL[END stable_id="~/.framework/functions/embeddings.ts:buildProcedureContent:function"]
695
725
  // CIL[DOC-VECTOR type="context" content="purpose='Extracts the procedure text for an item embedding.'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/audit.ts"]
696
726
  // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
697
727
  // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
@@ -710,7 +740,6 @@ function buildProcedureContent(item: any): string {
710
740
  * @calls firstNonEmpty
711
741
  * @cil-generated
712
742
  */
713
- // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:buildoutcomecontent:function" type="function" identity="buildOutcomeContent" parent="~/.framework/functions/embeddings.ts"]
714
743
  // CIL[DOC-MACRO purpose="Extracts the outcome text for an item embedding."]
715
744
  // CIL[DOC-RESPONSIBILITY responsibility="Picks the first available outcome or result field from item data."]
716
745
  // CIL[DOC-CONTEXT module="embeddings" layer="functions" related_files=".framework/functions/_shared/audit.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/llm.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/permissions.ts,.framework/functions/_shared/principal.ts,.framework/functions/embeddings.ts"]
@@ -719,6 +748,7 @@ function buildProcedureContent(item: any): string {
719
748
  // CIL[DOC-STABILITY stability="internal"]
720
749
  // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
721
750
  // CIL[DOC-AUDIENCE audience="developers"]
751
+ // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:buildOutcomeContent:function" type="function" identity="buildOutcomeContent" parent="~/.framework/functions/embeddings.ts"]
722
752
  function buildOutcomeContent(item: any): string {
723
753
  return firstNonEmpty(
724
754
  item.data?.outcome,
@@ -727,7 +757,7 @@ function buildOutcomeContent(item: any): string {
727
757
  item.data?.result,
728
758
  )
729
759
  }
730
- // CIL[END stable_id="~/.framework/functions/embeddings.ts:buildoutcomecontent:function"]
760
+ // CIL[END stable_id="~/.framework/functions/embeddings.ts:buildOutcomeContent:function"]
731
761
  // CIL[DOC-VECTOR type="context" content="purpose='Extracts the outcome text for an item embedding.'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/audit.ts"]
732
762
  // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
733
763
  // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
@@ -746,7 +776,6 @@ function buildOutcomeContent(item: any): string {
746
776
  * @calls firstNonEmpty
747
777
  * @cil-generated
748
778
  */
749
- // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:buildcontextcontent:function" type="function" identity="buildContextContent" parent="~/.framework/functions/embeddings.ts"]
750
779
  // CIL[DOC-MACRO purpose="Extracts the context text for an item embedding."]
751
780
  // CIL[DOC-RESPONSIBILITY responsibility="Picks the first available context or prerequisite field from item data."]
752
781
  // CIL[DOC-CONTEXT module="embeddings" layer="functions" related_files=".framework/functions/_shared/audit.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/llm.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/permissions.ts,.framework/functions/_shared/principal.ts,.framework/functions/embeddings.ts"]
@@ -755,6 +784,7 @@ function buildOutcomeContent(item: any): string {
755
784
  // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
756
785
  // CIL[DOC-STABILITY stability="stable"]
757
786
  // CIL[DOC-AUDIENCE audience="developers"]
787
+ // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:buildContextContent:function" type="function" identity="buildContextContent" parent="~/.framework/functions/embeddings.ts"]
758
788
  function buildContextContent(item: any): string {
759
789
  const steps = item.data?.ca_diagnostic_steps
760
790
  if (Array.isArray(steps) && steps.length) {
@@ -767,7 +797,7 @@ function buildContextContent(item: any): string {
767
797
  item.data?.product_area,
768
798
  )
769
799
  }
770
- // CIL[END stable_id="~/.framework/functions/embeddings.ts:buildcontextcontent:function"]
800
+ // CIL[END stable_id="~/.framework/functions/embeddings.ts:buildContextContent:function"]
771
801
  // CIL[DOC-VECTOR type="context" content="purpose='Extracts the context text for an item embedding.'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/audit.ts"]
772
802
  // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
773
803
  // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
@@ -788,7 +818,6 @@ function buildContextContent(item: any): string {
788
818
  * @stability stable
789
819
  * @cil-generated
790
820
  */
791
- // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:builderrorsignalcontent:function" type="function" identity="buildErrorSignalContent" parent="~/.framework/functions/embeddings.ts"]
792
821
  // CIL[DOC-MACRO purpose="Extracts error signals or code blocks for an item embedding."]
793
822
  // CIL[DOC-RESPONSIBILITY responsibility="Picks the first available error signature or code block from item data."]
794
823
  // CIL[DOC-CONTEXT module="embeddings" layer="functions" related_files=".framework/functions/_shared/audit.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/llm.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/permissions.ts,.framework/functions/_shared/principal.ts,.framework/functions/embeddings.ts"]
@@ -797,6 +826,7 @@ function buildContextContent(item: any): string {
797
826
  // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
798
827
  // CIL[DOC-STABILITY stability="stable"]
799
828
  // CIL[DOC-AUDIENCE audience="developers"]
829
+ // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:buildErrorSignalContent:function" type="function" identity="buildErrorSignalContent" parent="~/.framework/functions/embeddings.ts"]
800
830
  function buildErrorSignalContent(item: any): string {
801
831
  const sigs = item.data?.error_signatures
802
832
  if (Array.isArray(sigs) && sigs.length) return sigs.join('\n')
@@ -807,7 +837,7 @@ function buildErrorSignalContent(item: any): string {
807
837
  const codeBlocks = desc.match(/```[\s\S]*?```/g) || []
808
838
  return codeBlocks.map((b: string) => b.replace(/```\w*\n?/g, '')).join('\n').trim()
809
839
  }
810
- // CIL[END stable_id="~/.framework/functions/embeddings.ts:builderrorsignalcontent:function"]
840
+ // CIL[END stable_id="~/.framework/functions/embeddings.ts:buildErrorSignalContent:function"]
811
841
 
812
842
  /**
813
843
  * Builds a synchronous summary string for an item by extracting and formatting its title and description. This function is designed to provide a concise overview of an item embedding.
@@ -820,7 +850,6 @@ function buildErrorSignalContent(item: any): string {
820
850
  * @calls stripHtml
821
851
  * @cil-generated
822
852
  */
823
- // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:buildsummarycontentsync:function" type="function" identity="buildSummaryContentSync" parent="~/.framework/functions/embeddings.ts"]
824
853
  // CIL[DOC-VECTOR type="context" content="purpose='Extracts error signals or code blocks for an item embedding.'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/audit.ts"]
825
854
  // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
826
855
  // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
@@ -835,12 +864,13 @@ function buildErrorSignalContent(item: any): string {
835
864
  // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
836
865
  // CIL[DOC-STABILITY stability="stable"]
837
866
  // CIL[DOC-AUDIENCE audience="developers"]
867
+ // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:buildSummaryContentSync:function" type="function" identity="buildSummaryContentSync" parent="~/.framework/functions/embeddings.ts"]
838
868
  function buildSummaryContentSync(item: any): string {
839
869
 
840
870
  const desc = stripHtml(item.description || '')
841
871
  return `${item.title || ''}: ${desc.slice(0, 300)}`
842
872
  }
843
- // CIL[END stable_id="~/.framework/functions/embeddings.ts:buildsummarycontentsync:function"]
873
+ // CIL[END stable_id="~/.framework/functions/embeddings.ts:buildSummaryContentSync:function"]
844
874
  // CIL[DOC-VECTOR type="context" content="purpose='Builds a synchronous summary string for an item.'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/audit.ts"]
845
875
  // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
846
876
  // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
@@ -860,7 +890,6 @@ function buildSummaryContentSync(item: any): string {
860
890
  * @calls callOpenAIChat, buildSummaryContentSync
861
891
  * @cil-generated
862
892
  */
863
- // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:generateaisummary:function" type="function" identity="generateAiSummary" parent="~/.framework/functions/embeddings.ts"]
864
893
  // CIL[DOC-MACRO purpose="Generates an AI-written summary for an item, with a sync fallback."]
865
894
  // CIL[DOC-RESPONSIBILITY responsibility="Calls OpenAI chat to summarize an article, falling back to a synchronous summary on failure."]
866
895
  // CIL[DOC-STABILITY stability="internal"]
@@ -869,6 +898,7 @@ function buildSummaryContentSync(item: any): string {
869
898
  // CIL[DOC-CONTRACT inputs="item: any, ctx?: any" outputs="string summary" errors="none; failures are handled and fallback is returned" side_effects="calls external OpenAI chat API"]
870
899
  // CIL[DOC-MICRO logic_summary="Strips HTML and truncates the description, calls the LLM with a concise system prompt, and falls back to buildSummaryContentSync if the call fails." notable_decisions="none"]
871
900
  // CIL[DOC-AUDIENCE audience="developers"]
901
+ // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:generateAiSummary:function" type="function" identity="generateAiSummary" parent="~/.framework/functions/embeddings.ts"]
872
902
  async function generateAiSummary(item: any, ctx?: any): Promise<string> {
873
903
  const plain = stripHtml(item.description || '').slice(0, 3000)
874
904
  try {
@@ -886,7 +916,7 @@ async function generateAiSummary(item: any, ctx?: any): Promise<string> {
886
916
  return buildSummaryContentSync(item)
887
917
  }
888
918
  }
889
- // CIL[END stable_id="~/.framework/functions/embeddings.ts:generateaisummary:function"]
919
+ // CIL[END stable_id="~/.framework/functions/embeddings.ts:generateAiSummary:function"]
890
920
 
891
921
  // CIL[DOC-VECTOR type="context" content="purpose='Generates an AI-written summary for an item, with a sync fallback.'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/audit.ts"]
892
922
  // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
@@ -906,7 +936,6 @@ async function generateAiSummary(item: any, ctx?: any): Promise<string> {
906
936
  * @calls callOpenAIEmbeddings
907
937
  * @cil-generated
908
938
  */
909
- // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:callembeddingapi:function" type="function" identity="callEmbeddingApi" parent="~/.framework/functions/embeddings.ts"]
910
939
  // CIL[DOC-MACRO purpose="Calls the OpenAI embedding API and formats the result."]
911
940
  // CIL[DOC-RESPONSIBILITY responsibility="Converts text inputs into vector arrays from the embedding model."]
912
941
  // CIL[DOC-CONTEXT module="embeddings" layer="functions" related_files=".framework/functions/_shared/audit.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/llm.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/permissions.ts,.framework/functions/_shared/principal.ts,.framework/functions/embeddings.ts"]
@@ -915,13 +944,14 @@ async function generateAiSummary(item: any, ctx?: any): Promise<string> {
915
944
  // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
916
945
  // CIL[DOC-STABILITY stability="stable"]
917
946
  // CIL[DOC-AUDIENCE audience="developers"]
947
+ // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:callEmbeddingApi:function" type="function" identity="callEmbeddingApi" parent="~/.framework/functions/embeddings.ts"]
918
948
  async function callEmbeddingApi(inputs: string[], ctx?: any): Promise<string[]> {
919
949
  if (!inputs.length) return inputs.map(() => '')
920
950
  const j = await callOpenAIEmbeddings(ctx, inputs, 'text-embedding-3-small')
921
951
  const sorted = (j.data || []).sort((a: any, b: any) => a.index - b.index)
922
952
  return sorted.map((d: any) => `[${d.embedding.join(',')}]`)
923
953
  }
924
- // CIL[END stable_id="~/.framework/functions/embeddings.ts:callembeddingapi:function"]
954
+ // CIL[END stable_id="~/.framework/functions/embeddings.ts:callEmbeddingApi:function"]
925
955
  // CIL[DOC-VECTOR type="context" content="purpose='Calls the OpenAI embedding API and formats the result.'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/audit.ts"]
926
956
  // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
927
957
  // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
@@ -940,7 +970,6 @@ async function callEmbeddingApi(inputs: string[], ctx?: any): Promise<string[]>
940
970
  * @calls createHash
941
971
  * @cil-generated
942
972
  */
943
- // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:contenthash:function" type="function" identity="contentHash" parent="~/.framework/functions/embeddings.ts"]
944
973
  // CIL[DOC-MACRO purpose="Computes a short SHA-256 hash of text."]
945
974
  // CIL[DOC-RESPONSIBILITY responsibility="Generates a 16-hex-character content hash for embeddings."]
946
975
  // CIL[DOC-CONTEXT module="embeddings" layer="functions" related_files=".framework/functions/_shared/audit.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/llm.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/permissions.ts,.framework/functions/_shared/principal.ts,.framework/functions/embeddings.ts"]
@@ -949,10 +978,11 @@ async function callEmbeddingApi(inputs: string[], ctx?: any): Promise<string[]>
949
978
  // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
950
979
  // CIL[DOC-STABILITY stability="stable"]
951
980
  // CIL[DOC-AUDIENCE audience="developers"]
981
+ // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:contentHash:function" type="function" identity="contentHash" parent="~/.framework/functions/embeddings.ts"]
952
982
  function contentHash(text: string): string {
953
983
  return createHash('sha256').update(text).digest('hex').slice(0, 16)
954
984
  }
955
- // CIL[END stable_id="~/.framework/functions/embeddings.ts:contenthash:function"]
985
+ // CIL[END stable_id="~/.framework/functions/embeddings.ts:contentHash:function"]
956
986
  // CIL[DOC-VECTOR type="context" content="purpose='Computes a short SHA-256 hash of text.'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/audit.ts"]
957
987
  // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
958
988
  // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
@@ -970,7 +1000,6 @@ function contentHash(text: string): string {
970
1000
  * @stability stable
971
1001
  * @cil-generated
972
1002
  */
973
- // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:_platformaccountid:constant" type="constant" identity="_platformAccountId" parent="~/.framework/functions/embeddings.ts"]
974
1003
  // CIL[DOC-MACRO purpose="Cached platform account identifier for spine-system."]
975
1004
  // CIL[DOC-RESPONSIBILITY responsibility="Holds the cached spine-system account id to avoid repeated lookups."]
976
1005
  // CIL[DOC-CONTEXT module="embeddings" layer="functions" related_files=".framework/functions/_shared/audit.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/llm.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/permissions.ts,.framework/functions/_shared/principal.ts,.framework/functions/embeddings.ts"]
@@ -979,8 +1008,9 @@ function contentHash(text: string): string {
979
1008
  // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
980
1009
  // CIL[DOC-STABILITY stability="stable"]
981
1010
  // CIL[DOC-AUDIENCE audience="developers"]
1011
+
982
1012
  let _platformAccountId: string | null = null
983
- // CIL[END stable_id="~/.framework/functions/embeddings.ts:_platformaccountid:constant"]
1013
+
984
1014
  // CIL[DOC-VECTOR type="context" content="purpose='Cached platform account identifier for spine-system.'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/audit.ts"]
985
1015
  // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
986
1016
  // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
@@ -997,7 +1027,6 @@ let _platformAccountId: string | null = null
997
1027
  * @calls adminDb.from('accounts')
998
1028
  * @cil-generated
999
1029
  */
1000
- // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:getplatformaccountid:function" type="function" identity="getPlatformAccountId" parent="~/.framework/functions/embeddings.ts"]
1001
1030
  // CIL[DOC-MACRO purpose="Resolves and caches the spine-system platform account id."]
1002
1031
  // CIL[DOC-RESPONSIBILITY responsibility="Fetches the platform account from the accounts table and caches it."]
1003
1032
  // CIL[DOC-CONTEXT module="embeddings" layer="functions" related_files=".framework/functions/_shared/audit.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/llm.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/permissions.ts,.framework/functions/_shared/principal.ts,.framework/functions/embeddings.ts"]
@@ -1006,13 +1035,14 @@ let _platformAccountId: string | null = null
1006
1035
  // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
1007
1036
  // CIL[DOC-STABILITY stability="stable"]
1008
1037
  // CIL[DOC-AUDIENCE audience="developers"]
1038
+ // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:getPlatformAccountId:function" type="function" identity="getPlatformAccountId" parent="~/.framework/functions/embeddings.ts"]
1009
1039
  async function getPlatformAccountId(): Promise<string | null> {
1010
1040
  if (_platformAccountId) return _platformAccountId
1011
1041
  const { data } = await adminDb.from('accounts').select('id').eq('slug', 'spine-system').maybeSingle()
1012
1042
  _platformAccountId = data?.id ?? null
1013
1043
  return _platformAccountId
1014
1044
  }
1015
- // CIL[END stable_id="~/.framework/functions/embeddings.ts:getplatformaccountid:function"]
1045
+ // CIL[END stable_id="~/.framework/functions/embeddings.ts:getPlatformAccountId:function"]
1016
1046
  // CIL[DOC-VECTOR type="context" content="purpose='Resolves and caches the spine-system platform account id.'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/audit.ts"]
1017
1047
  // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
1018
1048
  // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
@@ -1031,7 +1061,6 @@ async function getPlatformAccountId(): Promise<string | null> {
1031
1061
  * @stability stable
1032
1062
  * @cil-generated
1033
1063
  */
1034
- // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:contentbuilder:type" type="type" identity="ContentBuilder" parent="~/.framework/functions/embeddings.ts"]
1035
1064
  // CIL[DOC-MACRO purpose="Type alias for embedding content builder functions."]
1036
1065
  // CIL[DOC-RESPONSIBILITY responsibility="Defines the function signature used by CONTENT_BUILDERS."]
1037
1066
  // CIL[DOC-CONTEXT module="embeddings" layer="functions" related_files=".framework/functions/_shared/audit.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/llm.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/permissions.ts,.framework/functions/_shared/principal.ts,.framework/functions/embeddings.ts"]
@@ -1040,8 +1069,9 @@ async function getPlatformAccountId(): Promise<string | null> {
1040
1069
  // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
1041
1070
  // CIL[DOC-STABILITY stability="stable"]
1042
1071
  // CIL[DOC-AUDIENCE audience="developers"]
1072
+ // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:ContentBuilder:type" type="type" identity="ContentBuilder" parent="~/.framework/functions/embeddings.ts"]
1043
1073
  type ContentBuilder = (item: any, meta?: any) => string
1044
- // CIL[END stable_id="~/.framework/functions/embeddings.ts:contentbuilder:type"]
1074
+ // CIL[END stable_id="~/.framework/functions/embeddings.ts:ContentBuilder:type"]
1045
1075
  // CIL[DOC-VECTOR type="context" content="purpose='Type alias for embedding content builder functions.'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/audit.ts"]
1046
1076
  // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
1047
1077
  // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
@@ -1057,7 +1087,6 @@ type ContentBuilder = (item: any, meta?: any) => string
1057
1087
  * @calls buildSemanticContent, buildStructureContent, buildIntentContent, buildCauseContent, buildProcedureContent, buildOutcomeContent, buildContextContent, buildErrorSignalContent
1058
1088
  * @cil-generated
1059
1089
  */
1060
- // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:content_builders:constant" type="constant" identity="CONTENT_BUILDERS" parent="~/.framework/functions/embeddings.ts"]
1061
1090
  // CIL[DOC-MACRO purpose="Mapping of vector type names to content builder functions."]
1062
1091
  // CIL[DOC-RESPONSIBILITY responsibility="Registers content builders for semantic, structure, intent, cause, procedure, outcome, context, and error_signal vectors."]
1063
1092
  // CIL[DOC-CONTEXT module="embeddings" layer="functions" related_files=".framework/functions/_shared/audit.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/llm.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/permissions.ts,.framework/functions/_shared/principal.ts,.framework/functions/embeddings.ts"]
@@ -1066,6 +1095,7 @@ type ContentBuilder = (item: any, meta?: any) => string
1066
1095
  // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
1067
1096
  // CIL[DOC-STABILITY stability="stable"]
1068
1097
  // CIL[DOC-AUDIENCE audience="developers"]
1098
+ // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:CONTENT_BUILDERS:constant" type="constant" identity="CONTENT_BUILDERS" parent="~/.framework/functions/embeddings.ts"]
1069
1099
  const CONTENT_BUILDERS: Record<string, ContentBuilder> = {
1070
1100
  semantic: buildSemanticContent,
1071
1101
  structure: (item, meta) => buildStructureContent(item, meta?.embedding_fields ?? []),
@@ -1077,7 +1107,7 @@ const CONTENT_BUILDERS: Record<string, ContentBuilder> = {
1077
1107
  error_signal: buildErrorSignalContent,
1078
1108
 
1079
1109
  }
1080
- // CIL[END stable_id="~/.framework/functions/embeddings.ts:content_builders:constant"]
1110
+ // CIL[END stable_id="~/.framework/functions/embeddings.ts:CONTENT_BUILDERS:constant"]
1081
1111
  // CIL[DOC-VECTOR type="context" content="purpose='Mapping of vector type names to content builder functions.'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/audit.ts"]
1082
1112
  // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
1083
1113
  // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
@@ -1093,7 +1123,6 @@ const CONTENT_BUILDERS: Record<string, ContentBuilder> = {
1093
1123
  * @calls sanitizeRecordData, adminDb.from, ctx.db.from
1094
1124
  * @cil-generated
1095
1125
  */
1096
- // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:list:constant" type="constant" identity="list" parent="~/.framework/functions/embeddings.ts"]
1097
1126
  // CIL[DOC-MACRO purpose="Lists embedding records with optional filters."]
1098
1127
  // CIL[DOC-RESPONSIBILITY responsibility="Returns a paginated, sanitized list of embeddings for the current account."]
1099
1128
  // CIL[DOC-CONTEXT module="embeddings" layer="functions" related_files=".framework/functions/_shared/audit.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/llm.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/permissions.ts,.framework/functions/_shared/principal.ts,.framework/functions/embeddings.ts"]
@@ -1102,10 +1131,13 @@ const CONTENT_BUILDERS: Record<string, ContentBuilder> = {
1102
1131
  // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
1103
1132
  // CIL[DOC-STABILITY stability="stable"]
1104
1133
  // CIL[DOC-AUDIENCE audience="developers"]
1134
+ // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:list:constant" type="constant" identity="list" parent="~/.framework/functions/embeddings.ts"]
1105
1135
  export const list = createHandler(async (ctx, _body) => {
1106
1136
  const { model_id, document_id, limit = 100, offset = 0 } = ctx.query || {}
1107
1137
 
1108
- if (!ctx.accountId) {
1138
+ const isSystem = isSystemPrincipal(ctx)
1139
+
1140
+ if (!isSystem && !ctx.accountId) {
1109
1141
  throw new Error('Account context required')
1110
1142
  }
1111
1143
 
@@ -1116,6 +1148,10 @@ export const list = createHandler(async (ctx, _body) => {
1116
1148
  .select('*')
1117
1149
  .order('created_at', { ascending: false })
1118
1150
 
1151
+ if (!isSystem) {
1152
+ query = query.eq('account_id', ctx.accountId)
1153
+ }
1154
+
1119
1155
  if (model_id) {
1120
1156
  query = query.eq('model_id', model_id)
1121
1157
  }
@@ -1150,7 +1186,6 @@ export const list = createHandler(async (ctx, _body) => {
1150
1186
  * @calls adminDb.from('embeddings'), ctx.db.from('embeddings'), sanitizeRecordData
1151
1187
  * @cil-generated
1152
1188
  */
1153
- // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:get:constant" type="constant" identity="get" parent="~/.framework/functions/embeddings.ts"]
1154
1189
  // CIL[DOC-MACRO purpose="Retrieves a single embedding by id."]
1155
1190
  // CIL[DOC-VECTOR type="context" content="purpose='Lists embedding records with optional filters.'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/audit.ts"]
1156
1191
  // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
@@ -1165,6 +1200,7 @@ export const list = createHandler(async (ctx, _body) => {
1165
1200
  // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
1166
1201
  // CIL[DOC-STABILITY stability="stable"]
1167
1202
  // CIL[DOC-AUDIENCE audience="developers"]
1203
+ // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:get:constant" type="constant" identity="get" parent="~/.framework/functions/embeddings.ts"]
1168
1204
  export const get = createHandler(async (ctx, _body) => {
1169
1205
  const { id } = ctx.query || {}
1170
1206
 
@@ -1174,11 +1210,17 @@ export const get = createHandler(async (ctx, _body) => {
1174
1210
 
1175
1211
  const db = isSystemAdmin(ctx.principal) ? adminDb : ctx.db
1176
1212
 
1177
- const { data, error: err } = await db
1213
+ let query = db
1178
1214
  .from('embeddings')
1179
1215
  .select('*')
1180
1216
  .eq('id', id)
1181
- .single()
1217
+
1218
+ if (!isSystemPrincipal(ctx)) {
1219
+ if (!ctx.accountId) throw new Error('Account context required')
1220
+ query = query.eq('account_id', ctx.accountId)
1221
+ }
1222
+
1223
+ const { data, error: err } = await query.single()
1182
1224
 
1183
1225
  if (err) throw err
1184
1226
 
@@ -1200,7 +1242,6 @@ export const get = createHandler(async (ctx, _body) => {
1200
1242
  * @calls ctx.db.from('embeddings')
1201
1243
  * @cil-generated
1202
1244
  */
1203
- // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:getstats:constant" type="constant" identity="getStats" parent="~/.framework/functions/embeddings.ts"]
1204
1245
  // CIL[DOC-MACRO purpose="Returns the total count of embeddings for the current account."]
1205
1246
  // CIL[DOC-RESPONSIBILITY responsibility="Counts the number of embeddings owned by the account."]
1206
1247
  // CIL[DOC-CONTEXT module="embeddings" layer="functions" related_files=".framework/functions/_shared/audit.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/llm.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/permissions.ts,.framework/functions/_shared/principal.ts,.framework/functions/embeddings.ts"]
@@ -1209,20 +1250,26 @@ export const get = createHandler(async (ctx, _body) => {
1209
1250
  // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
1210
1251
  // CIL[DOC-STABILITY stability="stable"]
1211
1252
  // CIL[DOC-AUDIENCE audience="developers"]
1253
+ // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:getStats:constant" type="constant" identity="getStats" parent="~/.framework/functions/embeddings.ts"]
1212
1254
  export const getStats = createHandler(async (ctx, _body) => {
1213
- if (!ctx.accountId) {
1255
+ const isSystem = isSystemPrincipal(ctx)
1256
+ if (!isSystem && !ctx.accountId) {
1214
1257
  throw new Error('Account context required')
1215
1258
  }
1216
1259
 
1217
- const { count, error: err } = await ctx.db
1260
+ let query = ctx.db
1218
1261
  .from('embeddings')
1219
1262
  .select('*', { count: 'exact', head: true })
1220
1263
 
1264
+ if (!isSystem) query = query.eq('account_id', ctx.accountId)
1265
+
1266
+ const { count, error: err } = await query
1267
+
1221
1268
  if (err) throw err
1222
1269
 
1223
1270
  return { total_embeddings: count || 0 }
1224
1271
  })
1225
- // CIL[END stable_id="~/.framework/functions/embeddings.ts:getstats:constant"]
1272
+ // CIL[END stable_id="~/.framework/functions/embeddings.ts:getStats:constant"]
1226
1273
  // CIL[DOC-VECTOR type="context" content="purpose='Returns the total count of embeddings for the current account.'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/audit.ts"]
1227
1274
  // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
1228
1275
  // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
@@ -1238,7 +1285,6 @@ export const getStats = createHandler(async (ctx, _body) => {
1238
1285
  * @calls ctx.db.from('embeddings'), emitLog
1239
1286
  * @cil-generated
1240
1287
  */
1241
- // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:batchcreate:constant" type="constant" identity="batchCreate" parent="~/.framework/functions/embeddings.ts"]
1242
1288
  // CIL[DOC-MACRO purpose="Bulk inserts multiple embedding records."]
1243
1289
  // CIL[DOC-RESPONSIBILITY responsibility="Creates many embeddings in one transaction and logs the batch."]
1244
1290
  // CIL[DOC-CONTEXT module="embeddings" layer="functions" related_files=".framework/functions/_shared/audit.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/llm.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/permissions.ts,.framework/functions/_shared/principal.ts,.framework/functions/embeddings.ts"]
@@ -1247,6 +1293,7 @@ export const getStats = createHandler(async (ctx, _body) => {
1247
1293
  // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
1248
1294
  // CIL[DOC-STABILITY stability="stable"]
1249
1295
  // CIL[DOC-AUDIENCE audience="developers"]
1296
+ // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:batchCreate:constant" type="constant" identity="batchCreate" parent="~/.framework/functions/embeddings.ts"]
1250
1297
  export const batchCreate = createHandler(async (ctx, body) => {
1251
1298
  const { embeddings_data } = body
1252
1299
 
@@ -1277,7 +1324,7 @@ export const batchCreate = createHandler(async (ctx, body) => {
1277
1324
 
1278
1325
  return data
1279
1326
  })
1280
- // CIL[END stable_id="~/.framework/functions/embeddings.ts:batchcreate:constant"]
1327
+ // CIL[END stable_id="~/.framework/functions/embeddings.ts:batchCreate:constant"]
1281
1328
  // CIL[DOC-VECTOR type="context" content="purpose='Bulk inserts multiple embedding records.'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/audit.ts"]
1282
1329
  // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
1283
1330
  // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
@@ -1293,7 +1340,6 @@ export const batchCreate = createHandler(async (ctx, body) => {
1293
1340
  * @calls ctx.db.from('embeddings'), emitLog
1294
1341
  * @cil-generated
1295
1342
  */
1296
- // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:deletebydocument:constant" type="constant" identity="deleteByDocument" parent="~/.framework/functions/embeddings.ts"]
1297
1343
  // CIL[DOC-MACRO purpose="Deletes all embeddings for a given document."]
1298
1344
  // CIL[DOC-RESPONSIBILITY responsibility="Removes embeddings associated with a document and logs the deletion."]
1299
1345
  // CIL[DOC-CONTEXT module="embeddings" layer="functions" related_files=".framework/functions/_shared/audit.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/llm.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/permissions.ts,.framework/functions/_shared/principal.ts,.framework/functions/embeddings.ts"]
@@ -1302,6 +1348,7 @@ export const batchCreate = createHandler(async (ctx, body) => {
1302
1348
  // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
1303
1349
  // CIL[DOC-STABILITY stability="stable"]
1304
1350
  // CIL[DOC-AUDIENCE audience="developers"]
1351
+ // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:deleteByDocument:constant" type="constant" identity="deleteByDocument" parent="~/.framework/functions/embeddings.ts"]
1305
1352
  export const deleteByDocument = createHandler(async (ctx, body) => {
1306
1353
  const { document_id } = body
1307
1354
 
@@ -1309,11 +1356,15 @@ export const deleteByDocument = createHandler(async (ctx, body) => {
1309
1356
  throw new Error('document_id is required')
1310
1357
  }
1311
1358
 
1312
- const { data, error: err } = await ctx.db
1359
+ const isSystem = isSystemPrincipal(ctx)
1360
+ if (!isSystem && !ctx.accountId) throw new Error('Account context required')
1361
+
1362
+ let query = ctx.db
1313
1363
  .from('embeddings')
1314
1364
  .delete()
1315
1365
  .eq('document_id', document_id)
1316
- .select()
1366
+ if (!isSystem) query = query.eq('account_id', ctx.accountId)
1367
+ const { data, error: err } = await query.select()
1317
1368
 
1318
1369
  if (err) throw err
1319
1370
 
@@ -1324,7 +1375,7 @@ export const deleteByDocument = createHandler(async (ctx, body) => {
1324
1375
 
1325
1376
  return { deleted_count: data?.length || 0 }
1326
1377
  })
1327
- // CIL[END stable_id="~/.framework/functions/embeddings.ts:deletebydocument:constant"]
1378
+ // CIL[END stable_id="~/.framework/functions/embeddings.ts:deleteByDocument:constant"]
1328
1379
  // CIL[DOC-VECTOR type="context" content="purpose='Deletes all embeddings for a given document.'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/audit.ts"]
1329
1380
  // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
1330
1381
  // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
@@ -1340,7 +1391,6 @@ export const deleteByDocument = createHandler(async (ctx, body) => {
1340
1391
  * @calls ctx.db.from('embeddings'), emitLog
1341
1392
  * @cil-generated
1342
1393
  */
1343
- // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:cleanup:constant" type="constant" identity="cleanup" parent="~/.framework/functions/embeddings.ts"]
1344
1394
  // CIL[DOC-MACRO purpose="Deletes embedding records older than a threshold."]
1345
1395
  // CIL[DOC-RESPONSIBILITY responsibility="Purges old embeddings based on a retention policy."]
1346
1396
  // CIL[DOC-CONTEXT module="embeddings" layer="functions" related_files=".framework/functions/_shared/audit.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/llm.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/permissions.ts,.framework/functions/_shared/principal.ts,.framework/functions/embeddings.ts"]
@@ -1349,18 +1399,23 @@ export const deleteByDocument = createHandler(async (ctx, body) => {
1349
1399
  // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
1350
1400
  // CIL[DOC-STABILITY stability="stable"]
1351
1401
  // CIL[DOC-AUDIENCE audience="developers"]
1402
+ // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:cleanup:constant" type="constant" identity="cleanup" parent="~/.framework/functions/embeddings.ts"]
1352
1403
  export const cleanup = createHandler(async (ctx, body) => {
1353
1404
  const { days_to_keep } = body
1354
1405
  const daysToKeep = days_to_keep || 365
1355
1406
 
1407
+ const isSystem = isSystemPrincipal(ctx)
1408
+ if (!isSystem && !ctx.accountId) throw new Error('Account context required')
1409
+
1356
1410
  const cutoff = new Date()
1357
1411
  cutoff.setDate(cutoff.getDate() - daysToKeep)
1358
1412
 
1359
- const { data, error: err } = await ctx.db
1413
+ let query = ctx.db
1360
1414
  .from('embeddings')
1361
1415
  .delete()
1362
1416
  .lt('created_at', cutoff.toISOString())
1363
- .select()
1417
+ if (!isSystem) query = query.eq('account_id', ctx.accountId)
1418
+ const { data, error: err } = await query.select()
1364
1419
 
1365
1420
  if (err) throw err
1366
1421
 
@@ -1389,7 +1444,6 @@ export const cleanup = createHandler(async (ctx, body) => {
1389
1444
  * @calls ctx.db.rpc
1390
1445
  * @cil-generated
1391
1446
  */
1392
- // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:searchsimilar:constant" type="constant" identity="searchSimilar" parent="~/.framework/functions/embeddings.ts"]
1393
1447
  // CIL[DOC-MACRO purpose="Performs vector similarity search over embeddings."]
1394
1448
  // CIL[DOC-RESPONSIBILITY responsibility="Returns embeddings whose vectors are within a threshold of a query embedding."]
1395
1449
  // CIL[DOC-CONTEXT module="embeddings" layer="functions" related_files=".framework/functions/_shared/audit.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/llm.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/permissions.ts,.framework/functions/_shared/principal.ts,.framework/functions/embeddings.ts"]
@@ -1398,6 +1452,7 @@ export const cleanup = createHandler(async (ctx, body) => {
1398
1452
  // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
1399
1453
  // CIL[DOC-STABILITY stability="stable"]
1400
1454
  // CIL[DOC-AUDIENCE audience="developers"]
1455
+ // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:searchSimilar:constant" type="constant" identity="searchSimilar" parent="~/.framework/functions/embeddings.ts"]
1401
1456
  export const searchSimilar = createHandler(async (ctx, body) => {
1402
1457
  const {
1403
1458
  query_embedding,
@@ -1414,10 +1469,16 @@ export const searchSimilar = createHandler(async (ctx, body) => {
1414
1469
  throw new Error('query_embedding is required for similarity search')
1415
1470
  }
1416
1471
 
1472
+ const isSystem = isSystemPrincipal(ctx)
1473
+ if (!isSystem && !ctx.accountId) {
1474
+ throw new Error('Account context required')
1475
+ }
1476
+
1417
1477
  const { data, error: err } = await ctx.db.rpc('match_embeddings', {
1418
1478
  query_embedding,
1419
1479
  match_count: parseInt(limit.toString()),
1420
- filter_account_ids: filter_account_ids ?? null,
1480
+ // Scoped callers may not widen the corpus beyond their own account.
1481
+ filter_account_ids: isSystem ? (filter_account_ids ?? null) : [ctx.accountId],
1421
1482
  filter_vector_type: filter_vector_type ?? null,
1422
1483
  similarity_threshold: parseFloat(threshold.toString()),
1423
1484
  filter_item_types: filter_item_types ?? null,
@@ -1433,7 +1494,7 @@ export const searchSimilar = createHandler(async (ctx, body) => {
1433
1494
  threshold: parseFloat(threshold.toString())
1434
1495
  }
1435
1496
  })
1436
- // CIL[END stable_id="~/.framework/functions/embeddings.ts:searchsimilar:constant"]
1497
+ // CIL[END stable_id="~/.framework/functions/embeddings.ts:searchSimilar:constant"]
1437
1498
  // CIL[DOC-VECTOR type="context" content="purpose='Performs vector similarity search over embeddings.'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/audit.ts"]
1438
1499
  // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
1439
1500
  // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
@@ -1449,7 +1510,6 @@ export const searchSimilar = createHandler(async (ctx, body) => {
1449
1510
  * @calls ctx.db.from('embeddings'), ctx.db.select, ctx.db.eq, ctx.db.textSearch, ctx.db.limit, ctx.db.in
1450
1511
  * @cil-generated
1451
1512
  */
1452
- // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:searchsemantic:constant" type="constant" identity="searchSemantic" parent="~/.framework/functions/embeddings.ts"]
1453
1513
  // CIL[DOC-MACRO purpose="Performs text search against embedding content."]
1454
1514
  // CIL[DOC-RESPONSIBILITY responsibility="Returns embeddings matching a text query using full-text search."]
1455
1515
  // CIL[DOC-CONTEXT module="embeddings" layer="functions" related_files=".framework/functions/_shared/audit.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/llm.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/permissions.ts,.framework/functions/_shared/principal.ts,.framework/functions/embeddings.ts"]
@@ -1458,6 +1518,7 @@ export const searchSimilar = createHandler(async (ctx, body) => {
1458
1518
  // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
1459
1519
  // CIL[DOC-STABILITY stability="stable"]
1460
1520
  // CIL[DOC-AUDIENCE audience="developers"]
1521
+ // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:searchSemantic:constant" type="constant" identity="searchSemantic" parent="~/.framework/functions/embeddings.ts"]
1461
1522
  export const searchSemantic = createHandler(async (ctx, body) => {
1462
1523
  const { query, model_id, document_ids, limit = 10 } = body || {}
1463
1524
 
@@ -1498,7 +1559,7 @@ export const searchSemantic = createHandler(async (ctx, body) => {
1498
1559
  query
1499
1560
  }
1500
1561
  })
1501
- // CIL[END stable_id="~/.framework/functions/embeddings.ts:searchsemantic:constant"]
1562
+ // CIL[END stable_id="~/.framework/functions/embeddings.ts:searchSemantic:constant"]
1502
1563
  // CIL[DOC-VECTOR type="context" content="purpose='Performs text search against embedding content.'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/audit.ts"]
1503
1564
  // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
1504
1565
  // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
@@ -1514,7 +1575,6 @@ export const searchSemantic = createHandler(async (ctx, body) => {
1514
1575
  * @calls adminDb.from('embeddings'), emitLog
1515
1576
  * @cil-generated
1516
1577
  */
1517
- // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:revoke:constant" type="constant" identity="revoke" parent="~/.framework/functions/embeddings.ts"]
1518
1578
  // CIL[DOC-MACRO purpose="Revokes all active embeddings for a document."]
1519
1579
  // CIL[DOC-RESPONSIBILITY responsibility="Marks embeddings for a document as revoked by setting revoked_at."]
1520
1580
  // CIL[DOC-CONTEXT module="embeddings" layer="functions" related_files=".framework/functions/_shared/audit.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/llm.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/permissions.ts,.framework/functions/_shared/principal.ts,.framework/functions/embeddings.ts"]
@@ -1523,16 +1583,21 @@ export const searchSemantic = createHandler(async (ctx, body) => {
1523
1583
  // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
1524
1584
  // CIL[DOC-STABILITY stability="stable"]
1525
1585
  // CIL[DOC-AUDIENCE audience="developers"]
1586
+ // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:revoke:constant" type="constant" identity="revoke" parent="~/.framework/functions/embeddings.ts"]
1526
1587
  export const revoke = createHandler(async (ctx, body) => {
1527
1588
  const { document_id } = body || {}
1528
1589
  if (!document_id) throw new Error('document_id is required')
1529
1590
 
1530
- const { data, error } = await adminDb
1591
+ const isSystem = isSystemPrincipal(ctx)
1592
+ if (!isSystem && !ctx.accountId) throw new Error('Account context required')
1593
+
1594
+ let query = adminDb
1531
1595
  .from('embeddings')
1532
1596
  .update({ revoked_at: new Date().toISOString() })
1533
1597
  .eq('document_id', document_id)
1534
1598
  .is('revoked_at', null)
1535
- .select('id')
1599
+ if (!isSystem) query = query.eq('account_id', ctx.accountId)
1600
+ const { data, error } = await query.select('id')
1536
1601
 
1537
1602
  if (error) throw error
1538
1603
 
@@ -1559,7 +1624,6 @@ export const revoke = createHandler(async (ctx, body) => {
1559
1624
  * @calls adminDb.from('embeddings'), emitLog
1560
1625
  * @cil-generated
1561
1626
  */
1562
- // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:approve:constant" type="constant" identity="approve" parent="~/.framework/functions/embeddings.ts"]
1563
1627
  // CIL[DOC-MACRO purpose="Approves all embeddings for a document."]
1564
1628
  // CIL[DOC-RESPONSIBILITY responsibility="Marks embeddings for a document as approved by setting approved_at and clearing revoked_at."]
1565
1629
  // CIL[DOC-CONTEXT module="embeddings" layer="functions" related_files=".framework/functions/_shared/audit.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/llm.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/permissions.ts,.framework/functions/_shared/principal.ts,.framework/functions/embeddings.ts"]
@@ -1568,16 +1632,21 @@ export const revoke = createHandler(async (ctx, body) => {
1568
1632
  // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
1569
1633
  // CIL[DOC-STABILITY stability="stable"]
1570
1634
  // CIL[DOC-AUDIENCE audience="developers"]
1635
+ // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:approve:constant" type="constant" identity="approve" parent="~/.framework/functions/embeddings.ts"]
1571
1636
  export const approve = createHandler(async (ctx, body) => {
1572
1637
  const { document_id } = body || {}
1573
1638
  if (!document_id) throw new Error('document_id is required')
1574
1639
 
1640
+ const isSystem = isSystemPrincipal(ctx)
1641
+ if (!isSystem && !ctx.accountId) throw new Error('Account context required')
1642
+
1575
1643
  const now = new Date().toISOString()
1576
- const { data, error } = await adminDb
1644
+ let query = adminDb
1577
1645
  .from('embeddings')
1578
1646
  .update({ approved_at: now, revoked_at: null })
1579
1647
  .eq('document_id', document_id)
1580
- .select('id')
1648
+ if (!isSystem) query = query.eq('account_id', ctx.accountId)
1649
+ const { data, error } = await query.select('id')
1581
1650
 
1582
1651
  if (error) throw error
1583
1652
 
@@ -1605,7 +1674,6 @@ export const approve = createHandler(async (ctx, body) => {
1605
1674
  * @errorHandling none
1606
1675
  * @cil-generated
1607
1676
  */
1608
- // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:handler:constant" type="constant" identity="handler" parent="~/.framework/functions/embeddings.ts"]
1609
1677
  // CIL[DOC-MACRO purpose="Netlify function router that dispatches embedding actions."]
1610
1678
  // CIL[DOC-RESPONSIBILITY responsibility="Routes HTTP requests to the correct embedding operation based on action and method."]
1611
1679
  // CIL[DOC-CONTEXT module="embeddings" layer="functions" related_files=".framework/functions/_shared/audit.ts,.framework/functions/_shared/db.ts,.framework/functions/_shared/llm.ts,.framework/functions/_shared/middleware.ts,.framework/functions/_shared/permissions.ts,.framework/functions/_shared/principal.ts,.framework/functions/embeddings.ts"]
@@ -1614,6 +1682,7 @@ export const approve = createHandler(async (ctx, body) => {
1614
1682
  // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
1615
1683
  // CIL[DOC-STABILITY stability="stable"]
1616
1684
  // CIL[DOC-AUDIENCE audience="developers"]
1685
+ // CIL[BEGIN stable_id="~/.framework/functions/embeddings.ts:handler:constant" type="constant" identity="handler" parent="~/.framework/functions/embeddings.ts"]
1617
1686
  export const handler = createHandler(async (ctx, body) => {
1618
1687
  const { action } = ctx.query || {}
1619
1688
  const method = ctx.query?.method || 'GET'