@undefineds.co/xpod 0.3.58 → 0.3.62

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 (806) hide show
  1. package/README.md +3 -0
  2. package/config/cli.json +88 -0
  3. package/config/cloud.json +32 -1
  4. package/config/components-ignore.json +3 -0
  5. package/config/extensions.local.initializer.json +44 -0
  6. package/config/resolver.json +86 -0
  7. package/config/xpod.base.json +4 -0
  8. package/dist/agents/AgentExecutorFactory.d.ts +3 -3
  9. package/dist/agents/AgentExecutorFactory.js +28 -15
  10. package/dist/agents/AgentExecutorFactory.js.map +1 -1
  11. package/dist/agents/BaseAgentExecutor.d.ts +2 -1
  12. package/dist/agents/BaseAgentExecutor.js +1 -0
  13. package/dist/agents/BaseAgentExecutor.js.map +1 -1
  14. package/dist/agents/ClaudeExecutor.d.ts +3 -1
  15. package/dist/agents/ClaudeExecutor.js +18 -12
  16. package/dist/agents/ClaudeExecutor.js.map +1 -1
  17. package/dist/agents/config/resolve.js +0 -21
  18. package/dist/agents/config/resolve.js.map +1 -1
  19. package/dist/agents/config/types.d.ts +2 -7
  20. package/dist/agents/config/types.js +2 -1
  21. package/dist/agents/config/types.js.map +1 -1
  22. package/dist/agents/types.d.ts +18 -0
  23. package/dist/agents/types.js.map +1 -1
  24. package/dist/ai/schema/types.d.ts +2 -1
  25. package/dist/ai/schema/types.js +1 -0
  26. package/dist/ai/schema/types.js.map +1 -1
  27. package/dist/ai/service/CredentialReader.d.ts +3 -1
  28. package/dist/ai/service/CredentialReader.js.map +1 -1
  29. package/dist/ai/service/CredentialReaderImpl.d.ts +3 -1
  30. package/dist/ai/service/CredentialReaderImpl.js +24 -2
  31. package/dist/ai/service/CredentialReaderImpl.js.map +1 -1
  32. package/dist/ai/service/EmbeddingServiceImpl.js +13 -2
  33. package/dist/ai/service/EmbeddingServiceImpl.js.map +1 -1
  34. package/dist/ai/service/ProviderRegistry.d.ts +4 -0
  35. package/dist/ai/service/ProviderRegistry.js.map +1 -1
  36. package/dist/ai/service/ProviderRegistry.jsonld +4 -0
  37. package/dist/ai/service/ProviderRegistryImpl.d.ts +4 -1
  38. package/dist/ai/service/ProviderRegistryImpl.js +26 -4
  39. package/dist/ai/service/ProviderRegistryImpl.js.map +1 -1
  40. package/dist/ai/service/ProviderRegistryImpl.jsonld +12 -0
  41. package/dist/ai/service/defaultEmbeddingProfile.d.ts +5 -0
  42. package/dist/ai/service/defaultEmbeddingProfile.js +31 -0
  43. package/dist/ai/service/defaultEmbeddingProfile.js.map +1 -0
  44. package/dist/ai/service/index.d.ts +1 -0
  45. package/dist/ai/service/index.js +1 -0
  46. package/dist/ai/service/index.js.map +1 -1
  47. package/dist/ai/service/types.d.ts +1 -0
  48. package/dist/ai/service/types.js.map +1 -1
  49. package/dist/api/ApiServer.js +17 -2
  50. package/dist/api/ApiServer.js.map +1 -1
  51. package/dist/api/ai-gateway/AiGatewayService.d.ts +106 -0
  52. package/dist/api/ai-gateway/AiGatewayService.js +527 -0
  53. package/dist/api/ai-gateway/AiGatewayService.js.map +1 -0
  54. package/dist/api/ai-gateway/auth/AiConnectionInvocationKeyIssuer.d.ts +38 -0
  55. package/dist/api/ai-gateway/auth/AiConnectionInvocationKeyIssuer.js +128 -0
  56. package/dist/api/ai-gateway/auth/AiConnectionInvocationKeyIssuer.js.map +1 -0
  57. package/dist/api/ai-gateway/auth/ClientCredentialsInternalPodAccessTokenProvider.d.ts +25 -0
  58. package/dist/api/ai-gateway/auth/ClientCredentialsInternalPodAccessTokenProvider.js +91 -0
  59. package/dist/api/ai-gateway/auth/ClientCredentialsInternalPodAccessTokenProvider.js.map +1 -0
  60. package/dist/api/ai-gateway/auth/GatewayApiKey.d.ts +28 -0
  61. package/dist/api/ai-gateway/auth/GatewayApiKey.js +162 -0
  62. package/dist/api/ai-gateway/auth/GatewayApiKey.js.map +1 -0
  63. package/dist/api/ai-gateway/auth/GatewayApiKeyAuthenticator.d.ts +56 -0
  64. package/dist/api/ai-gateway/auth/GatewayApiKeyAuthenticator.js +143 -0
  65. package/dist/api/ai-gateway/auth/GatewayApiKeyAuthenticator.js.map +1 -0
  66. package/dist/api/ai-gateway/auth/GatewayKeyLocatorCodec.d.ts +26 -0
  67. package/dist/api/ai-gateway/auth/GatewayKeyLocatorCodec.js +97 -0
  68. package/dist/api/ai-gateway/auth/GatewayKeyLocatorCodec.js.map +1 -0
  69. package/dist/api/ai-gateway/auth/GatewayPrincipal.d.ts +20 -0
  70. package/dist/api/ai-gateway/auth/GatewayPrincipal.js +37 -0
  71. package/dist/api/ai-gateway/auth/GatewayPrincipal.js.map +1 -0
  72. package/dist/api/ai-gateway/auth/InvocationTokenCodec.d.ts +41 -0
  73. package/dist/api/ai-gateway/auth/InvocationTokenCodec.js +221 -0
  74. package/dist/api/ai-gateway/auth/InvocationTokenCodec.js.map +1 -0
  75. package/dist/api/ai-gateway/auth/PodGatewayAccessKeyRepository.d.ts +54 -0
  76. package/dist/api/ai-gateway/auth/PodGatewayAccessKeyRepository.js +152 -0
  77. package/dist/api/ai-gateway/auth/PodGatewayAccessKeyRepository.js.map +1 -0
  78. package/dist/api/ai-gateway/connect/index.d.ts +367 -0
  79. package/dist/api/ai-gateway/connect/index.js +1061 -0
  80. package/dist/api/ai-gateway/connect/index.js.map +1 -0
  81. package/dist/api/ai-gateway/credentials/CloudKmsWrapper.d.ts +40 -0
  82. package/dist/api/ai-gateway/credentials/CloudKmsWrapper.js +59 -0
  83. package/dist/api/ai-gateway/credentials/CloudKmsWrapper.js.map +1 -0
  84. package/dist/api/ai-gateway/credentials/CredentialVault.d.ts +14 -0
  85. package/dist/api/ai-gateway/credentials/CredentialVault.js +11 -0
  86. package/dist/api/ai-gateway/credentials/CredentialVault.js.map +1 -0
  87. package/dist/api/ai-gateway/credentials/KeyWrapper.d.ts +27 -0
  88. package/dist/api/ai-gateway/credentials/KeyWrapper.js +3 -0
  89. package/dist/api/ai-gateway/credentials/KeyWrapper.js.map +1 -0
  90. package/dist/api/ai-gateway/credentials/LocalKeychainWrapper.d.ts +27 -0
  91. package/dist/api/ai-gateway/credentials/LocalKeychainWrapper.js +145 -0
  92. package/dist/api/ai-gateway/credentials/LocalKeychainWrapper.js.map +1 -0
  93. package/dist/api/ai-gateway/credentials/SecretCellCredentialVault.d.ts +13 -0
  94. package/dist/api/ai-gateway/credentials/SecretCellCredentialVault.js +133 -0
  95. package/dist/api/ai-gateway/credentials/SecretCellCredentialVault.js.map +1 -0
  96. package/dist/api/ai-gateway/credentials/SecretCellKeyWrapper.d.ts +23 -0
  97. package/dist/api/ai-gateway/credentials/SecretCellKeyWrapper.js +62 -0
  98. package/dist/api/ai-gateway/credentials/SecretCellKeyWrapper.js.map +1 -0
  99. package/dist/api/ai-gateway/credentials/WebCryptoCredentialVault.d.ts +23 -0
  100. package/dist/api/ai-gateway/credentials/WebCryptoCredentialVault.js +173 -0
  101. package/dist/api/ai-gateway/credentials/WebCryptoCredentialVault.js.map +1 -0
  102. package/dist/api/ai-gateway/errors.d.ts +21 -0
  103. package/dist/api/ai-gateway/errors.js +50 -0
  104. package/dist/api/ai-gateway/errors.js.map +1 -0
  105. package/dist/api/ai-gateway/protocol/ChatCompletionsFrontend.d.ts +6 -0
  106. package/dist/api/ai-gateway/protocol/ChatCompletionsFrontend.js +111 -0
  107. package/dist/api/ai-gateway/protocol/ChatCompletionsFrontend.js.map +1 -0
  108. package/dist/api/ai-gateway/protocol/MessagesFrontend.d.ts +6 -0
  109. package/dist/api/ai-gateway/protocol/MessagesFrontend.js +99 -0
  110. package/dist/api/ai-gateway/protocol/MessagesFrontend.js.map +1 -0
  111. package/dist/api/ai-gateway/protocol/ResponsesFrontend.d.ts +6 -0
  112. package/dist/api/ai-gateway/protocol/ResponsesFrontend.js +232 -0
  113. package/dist/api/ai-gateway/protocol/ResponsesFrontend.js.map +1 -0
  114. package/dist/api/ai-gateway/protocol/index.d.ts +3 -0
  115. package/dist/api/ai-gateway/protocol/index.js +10 -0
  116. package/dist/api/ai-gateway/protocol/index.js.map +1 -0
  117. package/dist/api/ai-gateway/providers/AnthropicRuntimeAdapter.d.ts +7 -0
  118. package/dist/api/ai-gateway/providers/AnthropicRuntimeAdapter.js +37 -0
  119. package/dist/api/ai-gateway/providers/AnthropicRuntimeAdapter.js.map +1 -0
  120. package/dist/api/ai-gateway/providers/BailianRuntimeAdapter.d.ts +9 -0
  121. package/dist/api/ai-gateway/providers/BailianRuntimeAdapter.js +127 -0
  122. package/dist/api/ai-gateway/providers/BailianRuntimeAdapter.js.map +1 -0
  123. package/dist/api/ai-gateway/providers/DeepSeekRuntimeAdapter.d.ts +8 -0
  124. package/dist/api/ai-gateway/providers/DeepSeekRuntimeAdapter.js +47 -0
  125. package/dist/api/ai-gateway/providers/DeepSeekRuntimeAdapter.js.map +1 -0
  126. package/dist/api/ai-gateway/providers/KimiRuntimeAdapter.d.ts +8 -0
  127. package/dist/api/ai-gateway/providers/KimiRuntimeAdapter.js +57 -0
  128. package/dist/api/ai-gateway/providers/KimiRuntimeAdapter.js.map +1 -0
  129. package/dist/api/ai-gateway/providers/OpenAiCompatibleRuntimeAdapter.d.ts +1 -0
  130. package/dist/api/ai-gateway/providers/OpenAiCompatibleRuntimeAdapter.js +6 -0
  131. package/dist/api/ai-gateway/providers/OpenAiCompatibleRuntimeAdapter.js.map +1 -0
  132. package/dist/api/ai-gateway/providers/OpenAiRuntimeAdapter.d.ts +13 -0
  133. package/dist/api/ai-gateway/providers/OpenAiRuntimeAdapter.js +34 -0
  134. package/dist/api/ai-gateway/providers/OpenAiRuntimeAdapter.js.map +1 -0
  135. package/dist/api/ai-gateway/providers/ProviderRegistry.d.ts +68 -0
  136. package/dist/api/ai-gateway/providers/ProviderRegistry.js +288 -0
  137. package/dist/api/ai-gateway/providers/ProviderRegistry.js.map +1 -0
  138. package/dist/api/ai-gateway/providers/ProviderRuntimeAdapter.d.ts +88 -0
  139. package/dist/api/ai-gateway/providers/ProviderRuntimeAdapter.js +645 -0
  140. package/dist/api/ai-gateway/providers/ProviderRuntimeAdapter.js.map +1 -0
  141. package/dist/api/ai-gateway/providers/ProviderRuntimeRegistry.d.ts +13 -0
  142. package/dist/api/ai-gateway/providers/ProviderRuntimeRegistry.js +48 -0
  143. package/dist/api/ai-gateway/providers/ProviderRuntimeRegistry.js.map +1 -0
  144. package/dist/api/ai-gateway/providers/index.d.ts +9 -0
  145. package/dist/api/ai-gateway/providers/index.js +26 -0
  146. package/dist/api/ai-gateway/providers/index.js.map +1 -0
  147. package/dist/api/ai-gateway/quota/AnthropicQuotaAdapter.d.ts +5 -0
  148. package/dist/api/ai-gateway/quota/AnthropicQuotaAdapter.js +21 -0
  149. package/dist/api/ai-gateway/quota/AnthropicQuotaAdapter.js.map +1 -0
  150. package/dist/api/ai-gateway/quota/BailianQuotaAdapter.d.ts +5 -0
  151. package/dist/api/ai-gateway/quota/BailianQuotaAdapter.js +21 -0
  152. package/dist/api/ai-gateway/quota/BailianQuotaAdapter.js.map +1 -0
  153. package/dist/api/ai-gateway/quota/DeepSeekQuotaAdapter.d.ts +10 -0
  154. package/dist/api/ai-gateway/quota/DeepSeekQuotaAdapter.js +83 -0
  155. package/dist/api/ai-gateway/quota/DeepSeekQuotaAdapter.js.map +1 -0
  156. package/dist/api/ai-gateway/quota/KimiQuotaAdapter.d.ts +10 -0
  157. package/dist/api/ai-gateway/quota/KimiQuotaAdapter.js +70 -0
  158. package/dist/api/ai-gateway/quota/KimiQuotaAdapter.js.map +1 -0
  159. package/dist/api/ai-gateway/quota/OpenAiQuotaAdapter.d.ts +5 -0
  160. package/dist/api/ai-gateway/quota/OpenAiQuotaAdapter.js +21 -0
  161. package/dist/api/ai-gateway/quota/OpenAiQuotaAdapter.js.map +1 -0
  162. package/dist/api/ai-gateway/quota/ProviderQuotaAdapter.d.ts +214 -0
  163. package/dist/api/ai-gateway/quota/ProviderQuotaAdapter.js +511 -0
  164. package/dist/api/ai-gateway/quota/ProviderQuotaAdapter.js.map +1 -0
  165. package/dist/api/ai-gateway/quota/index.d.ts +6 -0
  166. package/dist/api/ai-gateway/quota/index.js +23 -0
  167. package/dist/api/ai-gateway/quota/index.js.map +1 -0
  168. package/dist/api/ai-gateway/routing/InMemorySessionAffinityStore.d.ts +26 -0
  169. package/dist/api/ai-gateway/routing/InMemorySessionAffinityStore.js +67 -0
  170. package/dist/api/ai-gateway/routing/InMemorySessionAffinityStore.js.map +1 -0
  171. package/dist/api/ai-gateway/routing/ModelRouter.d.ts +84 -0
  172. package/dist/api/ai-gateway/routing/ModelRouter.js +274 -0
  173. package/dist/api/ai-gateway/routing/ModelRouter.js.map +1 -0
  174. package/dist/api/ai-gateway/routing/RedisSessionAffinityStore.d.ts +39 -0
  175. package/dist/api/ai-gateway/routing/RedisSessionAffinityStore.js +122 -0
  176. package/dist/api/ai-gateway/routing/RedisSessionAffinityStore.js.map +1 -0
  177. package/dist/api/ai-gateway/routing/SessionAffinityStore.d.ts +49 -0
  178. package/dist/api/ai-gateway/routing/SessionAffinityStore.js +66 -0
  179. package/dist/api/ai-gateway/routing/SessionAffinityStore.js.map +1 -0
  180. package/dist/api/ai-gateway/service-access/AiConnectionServiceAccess.d.ts +25 -0
  181. package/dist/api/ai-gateway/service-access/AiConnectionServiceAccess.js +50 -0
  182. package/dist/api/ai-gateway/service-access/AiConnectionServiceAccess.js.map +1 -0
  183. package/dist/api/ai-gateway/types.d.ts +112 -0
  184. package/dist/api/ai-gateway/types.js +305 -0
  185. package/dist/api/ai-gateway/types.js.map +1 -0
  186. package/dist/api/auth/AuthContext.d.ts +18 -3
  187. package/dist/api/auth/AuthContext.js +13 -2
  188. package/dist/api/auth/AuthContext.js.map +1 -1
  189. package/dist/api/auth/Authenticator.d.ts +3 -0
  190. package/dist/api/auth/Authenticator.js.map +1 -1
  191. package/dist/api/auth/ClientCredentialsAuthenticator.d.ts +2 -6
  192. package/dist/api/auth/ClientCredentialsAuthenticator.js +12 -30
  193. package/dist/api/auth/ClientCredentialsAuthenticator.js.map +1 -1
  194. package/dist/api/auth/SolidTokenAuthenticator.d.ts +2 -0
  195. package/dist/api/auth/SolidTokenAuthenticator.js +88 -2
  196. package/dist/api/auth/SolidTokenAuthenticator.js.map +1 -1
  197. package/dist/api/auth/TokenIdentity.d.ts +6 -0
  198. package/dist/api/auth/TokenIdentity.js +31 -0
  199. package/dist/api/auth/TokenIdentity.js.map +1 -0
  200. package/dist/api/chatkit/ai-provider.d.ts +9 -23
  201. package/dist/api/chatkit/ai-provider.js +30 -153
  202. package/dist/api/chatkit/ai-provider.js.map +1 -1
  203. package/dist/api/chatkit/default-agent.d.ts +24 -15
  204. package/dist/api/chatkit/default-agent.js +24 -83
  205. package/dist/api/chatkit/default-agent.js.map +1 -1
  206. package/dist/api/chatkit/index.d.ts +2 -1
  207. package/dist/api/chatkit/index.js +3 -1
  208. package/dist/api/chatkit/index.js.map +1 -1
  209. package/dist/api/chatkit/pod-store.d.ts +13 -1
  210. package/dist/api/chatkit/pod-store.js +127 -7
  211. package/dist/api/chatkit/pod-store.js.map +1 -1
  212. package/dist/api/chatkit/runtime/AcpAgentRuntime.d.ts +0 -1
  213. package/dist/api/chatkit/runtime/AcpAgentRuntime.js +14 -51
  214. package/dist/api/chatkit/runtime/AcpAgentRuntime.js.map +1 -1
  215. package/dist/api/chatkit/runtime/AcpRunner.js +2 -1
  216. package/dist/api/chatkit/runtime/AcpRunner.js.map +1 -1
  217. package/dist/api/chatkit/runtime/CodexRuntimeProjector.d.ts +15 -1
  218. package/dist/api/chatkit/runtime/CodexRuntimeProjector.js +52 -34
  219. package/dist/api/chatkit/runtime/CodexRuntimeProjector.js.map +1 -1
  220. package/dist/api/chatkit/service.d.ts +8 -1
  221. package/dist/api/chatkit/service.js +46 -5
  222. package/dist/api/chatkit/service.js.map +1 -1
  223. package/dist/api/chatkit/store.d.ts +23 -1
  224. package/dist/api/chatkit/store.js +56 -0
  225. package/dist/api/chatkit/store.js.map +1 -1
  226. package/dist/api/chatkit/types.d.ts +1 -0
  227. package/dist/api/chatkit/types.js.map +1 -1
  228. package/dist/api/container/common.js +286 -13
  229. package/dist/api/container/common.js.map +1 -1
  230. package/dist/api/container/index.js +126 -6
  231. package/dist/api/container/index.js.map +1 -1
  232. package/dist/api/container/local.js +50 -6
  233. package/dist/api/container/local.js.map +1 -1
  234. package/dist/api/container/rdf.d.ts +15 -0
  235. package/dist/api/container/rdf.js +90 -0
  236. package/dist/api/container/rdf.js.map +1 -0
  237. package/dist/api/container/routes.js +151 -11
  238. package/dist/api/container/routes.js.map +1 -1
  239. package/dist/api/container/types.d.ts +96 -0
  240. package/dist/api/container/types.js.map +1 -1
  241. package/dist/api/handlers/AdminHandler.d.ts +25 -2
  242. package/dist/api/handlers/AdminHandler.js +60 -10
  243. package/dist/api/handlers/AdminHandler.js.map +1 -1
  244. package/dist/api/handlers/AiClientConfigurationHandler.d.ts +7 -0
  245. package/dist/api/handlers/AiClientConfigurationHandler.js +202 -0
  246. package/dist/api/handlers/AiClientConfigurationHandler.js.map +1 -0
  247. package/dist/api/handlers/AiGatewayHandler.d.ts +23 -0
  248. package/dist/api/handlers/AiGatewayHandler.js +231 -0
  249. package/dist/api/handlers/AiGatewayHandler.js.map +1 -0
  250. package/dist/api/handlers/AiGatewayManagementHandler.d.ts +24 -0
  251. package/dist/api/handlers/AiGatewayManagementHandler.js +503 -0
  252. package/dist/api/handlers/AiGatewayManagementHandler.js.map +1 -0
  253. package/dist/api/handlers/ChatHandler.d.ts +11 -12
  254. package/dist/api/handlers/ChatHandler.js +12 -219
  255. package/dist/api/handlers/ChatHandler.js.map +1 -1
  256. package/dist/api/handlers/DashboardHandler.js +22 -116
  257. package/dist/api/handlers/DashboardHandler.js.map +1 -1
  258. package/dist/api/handlers/NetworkSettingsHandler.d.ts +97 -0
  259. package/dist/api/handlers/NetworkSettingsHandler.js +511 -0
  260. package/dist/api/handlers/NetworkSettingsHandler.js.map +1 -0
  261. package/dist/api/handlers/PodSettingsHandler.d.ts +79 -0
  262. package/dist/api/handlers/PodSettingsHandler.js +162 -0
  263. package/dist/api/handlers/PodSettingsHandler.js.map +1 -0
  264. package/dist/api/handlers/ProvisionHandler.d.ts +3 -1
  265. package/dist/api/handlers/ProvisionHandler.js +22 -87
  266. package/dist/api/handlers/ProvisionHandler.js.map +1 -1
  267. package/dist/api/handlers/RdfStatsHandler.d.ts +6 -0
  268. package/dist/api/handlers/RdfStatsHandler.js +85 -0
  269. package/dist/api/handlers/RdfStatsHandler.js.map +1 -0
  270. package/dist/api/handlers/SettingsHandler.d.ts +5 -0
  271. package/dist/api/handlers/SettingsHandler.js +13 -0
  272. package/dist/api/handlers/SettingsHandler.js.map +1 -0
  273. package/dist/api/handlers/StaticSpaHandler.d.ts +8 -0
  274. package/dist/api/handlers/StaticSpaHandler.js +102 -0
  275. package/dist/api/handlers/StaticSpaHandler.js.map +1 -0
  276. package/dist/api/handlers/index.d.ts +1 -0
  277. package/dist/api/handlers/index.js +1 -0
  278. package/dist/api/handlers/index.js.map +1 -1
  279. package/dist/api/http/readBoundedJsonBody.d.ts +14 -0
  280. package/dist/api/http/readBoundedJsonBody.js +58 -0
  281. package/dist/api/http/readBoundedJsonBody.js.map +1 -0
  282. package/dist/api/middleware/AuthMiddleware.d.ts +1 -0
  283. package/dist/api/middleware/AuthMiddleware.js +33 -4
  284. package/dist/api/middleware/AuthMiddleware.js.map +1 -1
  285. package/dist/api/runs/AgentRuntimeTypes.d.ts +18 -3
  286. package/dist/api/runs/AgentRuntimeTypes.js +61 -0
  287. package/dist/api/runs/AgentRuntimeTypes.js.map +1 -1
  288. package/dist/api/runs/InngestRunExecutionBackend.d.ts +28 -3
  289. package/dist/api/runs/InngestRunExecutionBackend.js +26 -3
  290. package/dist/api/runs/InngestRunExecutionBackend.js.map +1 -1
  291. package/dist/api/runs/ManagedRunWorker.d.ts +4 -1
  292. package/dist/api/runs/ManagedRunWorker.js +39 -8
  293. package/dist/api/runs/ManagedRunWorker.js.map +1 -1
  294. package/dist/api/runs/PiAgentRuntimeDriver.d.ts +5 -1
  295. package/dist/api/runs/PiAgentRuntimeDriver.js +94 -57
  296. package/dist/api/runs/PiAgentRuntimeDriver.js.map +1 -1
  297. package/dist/api/runs/RdfRunContextRetriever.d.ts +46 -0
  298. package/dist/api/runs/RdfRunContextRetriever.js +277 -0
  299. package/dist/api/runs/RdfRunContextRetriever.js.map +1 -0
  300. package/dist/api/runs/RunExecutionBackend.d.ts +38 -0
  301. package/dist/api/runs/RunExecutionBackend.js.map +1 -1
  302. package/dist/api/runs/RunStateCenter.d.ts +18 -3
  303. package/dist/api/runs/RunStateCenter.js +85 -24
  304. package/dist/api/runs/RunStateCenter.js.map +1 -1
  305. package/dist/api/runtime.js +163 -3
  306. package/dist/api/runtime.js.map +1 -1
  307. package/dist/api/service/AiClientConfigurationService.d.ts +97 -0
  308. package/dist/api/service/AiClientConfigurationService.js +379 -0
  309. package/dist/api/service/AiClientConfigurationService.js.map +1 -0
  310. package/dist/api/service/RdfBenchmarkReportCatalog.d.ts +86 -0
  311. package/dist/api/service/RdfBenchmarkReportCatalog.js +349 -0
  312. package/dist/api/service/RdfBenchmarkReportCatalog.js.map +1 -0
  313. package/dist/api/service/RdfBenchmarkReportGate.d.ts +78 -0
  314. package/dist/api/service/RdfBenchmarkReportGate.js +197 -0
  315. package/dist/api/service/RdfBenchmarkReportGate.js.map +1 -0
  316. package/dist/api/service/RdfSearchIndexingService.d.ts +113 -0
  317. package/dist/api/service/RdfSearchIndexingService.js +272 -0
  318. package/dist/api/service/RdfSearchIndexingService.js.map +1 -0
  319. package/dist/api/service/RdfSearchIndexingSolidFsSyncer.d.ts +27 -0
  320. package/dist/api/service/RdfSearchIndexingSolidFsSyncer.js +90 -0
  321. package/dist/api/service/RdfSearchIndexingSolidFsSyncer.js.map +1 -0
  322. package/dist/api/service/RdfStorageStatsService.d.ts +31 -0
  323. package/dist/api/service/RdfStorageStatsService.js +97 -0
  324. package/dist/api/service/RdfStorageStatsService.js.map +1 -0
  325. package/dist/api/service/VectorStoreService.d.ts +2 -0
  326. package/dist/api/service/VectorStoreService.js +70 -2
  327. package/dist/api/service/VectorStoreService.js.map +1 -1
  328. package/dist/api/service/VercelChatService.d.ts +27 -38
  329. package/dist/api/service/VercelChatService.js +153 -505
  330. package/dist/api/service/VercelChatService.js.map +1 -1
  331. package/dist/api/service/provider-http-transport.d.ts +21 -0
  332. package/dist/api/service/provider-http-transport.js +108 -2
  333. package/dist/api/service/provider-http-transport.js.map +1 -1
  334. package/dist/api/service/provider-registry.d.ts +5 -7
  335. package/dist/api/service/provider-registry.js +81 -64
  336. package/dist/api/service/provider-registry.js.map +1 -1
  337. package/dist/api/tasks/InngestTaskScheduler.d.ts +44 -4
  338. package/dist/api/tasks/TaskMaterializer.d.ts +10 -1
  339. package/dist/api/tasks/TaskMaterializer.js +39 -4
  340. package/dist/api/tasks/TaskMaterializer.js.map +1 -1
  341. package/dist/api/tasks/TaskService.d.ts +5 -1
  342. package/dist/api/tasks/TaskService.js +3 -0
  343. package/dist/api/tasks/TaskService.js.map +1 -1
  344. package/dist/cli/commands/rdf.d.ts +9 -0
  345. package/dist/cli/commands/rdf.js +66 -1
  346. package/dist/cli/commands/rdf.js.map +1 -1
  347. package/dist/cli/commands/start.js +3 -0
  348. package/dist/cli/commands/start.js.map +1 -1
  349. package/dist/cli/lib/solid-auth.d.ts +3 -3
  350. package/dist/cli/lib/solid-auth.js +4 -4
  351. package/dist/cli/lib/solid-auth.js.map +1 -1
  352. package/dist/components/components.jsonld +16 -0
  353. package/dist/components/context.jsonld +815 -28
  354. package/dist/document/Chunker.jsonld +110 -0
  355. package/dist/document/{DocumentParser.d.ts → DocumentReader.d.ts} +23 -11
  356. package/dist/document/{DocumentParser.js → DocumentReader.js} +2 -2
  357. package/dist/document/DocumentReader.js.map +1 -0
  358. package/dist/document/DocumentReader.jsonld +82 -0
  359. package/dist/document/HeadingChunker.jsonld +41 -0
  360. package/dist/document/{JinaDocumentParser.d.ts → JinaReader.d.ts} +7 -7
  361. package/dist/document/{JinaDocumentParser.js → JinaReader.js} +12 -12
  362. package/dist/document/JinaReader.js.map +1 -0
  363. package/dist/document/JinaReader.jsonld +133 -0
  364. package/dist/document/L0SourceSummary.d.ts +103 -0
  365. package/dist/document/L0SourceSummary.js +157 -0
  366. package/dist/document/L0SourceSummary.js.map +1 -0
  367. package/dist/document/L0SourceSummary.jsonld +326 -0
  368. package/dist/document/PaddleOcrReader.d.ts +40 -0
  369. package/dist/document/PaddleOcrReader.js +53 -0
  370. package/dist/document/PaddleOcrReader.js.map +1 -0
  371. package/dist/document/PaddleOcrReader.jsonld +234 -0
  372. package/dist/document/ReaderAiConfig.d.ts +50 -0
  373. package/dist/document/ReaderAiConfig.js +109 -0
  374. package/dist/document/ReaderAiConfig.js.map +1 -0
  375. package/dist/document/ReaderAiConfig.jsonld +185 -0
  376. package/dist/document/ReaderPolicy.d.ts +89 -0
  377. package/dist/document/ReaderPolicy.js +158 -0
  378. package/dist/document/ReaderPolicy.js.map +1 -0
  379. package/dist/document/ReaderPolicy.jsonld +218 -0
  380. package/dist/document/index.d.ts +6 -2
  381. package/dist/document/index.js +6 -2
  382. package/dist/document/index.js.map +1 -1
  383. package/dist/edge/DdnsManager.d.ts +1 -1
  384. package/dist/edge/DdnsManager.js.map +1 -1
  385. package/dist/edge/EdgeNodeAgent.d.ts +4 -0
  386. package/dist/edge/EdgeNodeAgent.js +6 -0
  387. package/dist/edge/EdgeNodeAgent.js.map +1 -1
  388. package/dist/edge/EdgeNodeAgent.jsonld +8 -0
  389. package/dist/edge/EdgeNodeAgentInitializer.d.ts +16 -0
  390. package/dist/edge/EdgeNodeAgentInitializer.js +51 -0
  391. package/dist/edge/EdgeNodeAgentInitializer.js.map +1 -1
  392. package/dist/edge/EdgeNodeAgentInitializer.jsonld +250 -0
  393. package/dist/edge/EdgeNodeCertificateCapabilityBridge.d.ts +34 -0
  394. package/dist/edge/EdgeNodeCertificateCapabilityBridge.js +111 -0
  395. package/dist/edge/EdgeNodeCertificateCapabilityBridge.js.map +1 -0
  396. package/dist/edge/acme/AcmeCertificateManager.d.ts +14 -1
  397. package/dist/edge/acme/AcmeCertificateManager.js +67 -7
  398. package/dist/edge/acme/AcmeCertificateManager.js.map +1 -1
  399. package/dist/edge/acme/AcmeCertificateManager.jsonld +22 -2
  400. package/dist/edge/acme/ClusterCertificateManager.d.ts +12 -0
  401. package/dist/edge/acme/ClusterCertificateManager.js +38 -0
  402. package/dist/edge/acme/ClusterCertificateManager.js.map +1 -1
  403. package/dist/extensions/ExtensionRuntime.d.ts +17 -0
  404. package/dist/extensions/ExtensionRuntime.js +171 -0
  405. package/dist/extensions/ExtensionRuntime.js.map +1 -0
  406. package/dist/extensions/PodCredentialResolver.d.ts +23 -0
  407. package/dist/extensions/PodCredentialResolver.js +139 -0
  408. package/dist/extensions/PodCredentialResolver.js.map +1 -0
  409. package/dist/extensions/index.d.ts +3 -0
  410. package/dist/extensions/index.js +20 -0
  411. package/dist/extensions/index.js.map +1 -0
  412. package/dist/extensions/types.d.ts +73 -0
  413. package/dist/extensions/types.js +3 -0
  414. package/dist/extensions/types.js.map +1 -0
  415. package/dist/http/SubgraphSparqlHttpHandler.d.ts +20 -1
  416. package/dist/http/SubgraphSparqlHttpHandler.js +324 -43
  417. package/dist/http/SubgraphSparqlHttpHandler.js.map +1 -1
  418. package/dist/http/SubgraphSparqlHttpHandler.jsonld +87 -0
  419. package/dist/identity/drizzle/EdgeNodeRepository.js +3 -2
  420. package/dist/identity/drizzle/EdgeNodeRepository.js.map +1 -1
  421. package/dist/identity/drizzle/schema.pg.js +1 -1
  422. package/dist/identity/drizzle/schema.pg.js.map +1 -1
  423. package/dist/identity/drizzle/schema.sqlite.js +1 -1
  424. package/dist/identity/drizzle/schema.sqlite.js.map +1 -1
  425. package/dist/identity/oidc/ScopedPickWebIdHandler.js +5 -5
  426. package/dist/identity/oidc/ScopedPickWebIdHandler.js.map +1 -1
  427. package/dist/index.d.ts +12 -2
  428. package/dist/index.js +13 -1
  429. package/dist/index.js.map +1 -1
  430. package/dist/main.js +3 -0
  431. package/dist/main.js.map +1 -1
  432. package/dist/provision/LocalProvisionState.d.ts +28 -0
  433. package/dist/provision/LocalProvisionState.js +124 -0
  434. package/dist/provision/LocalProvisionState.js.map +1 -0
  435. package/dist/provision/ProvisionCodeCodec.d.ts +7 -3
  436. package/dist/provision/ProvisionCodeCodec.js +10 -3
  437. package/dist/provision/ProvisionCodeCodec.js.map +1 -1
  438. package/dist/provision/ProvisionPodCreator.d.ts +15 -1
  439. package/dist/provision/ProvisionPodCreator.js +68 -1
  440. package/dist/provision/ProvisionPodCreator.js.map +1 -1
  441. package/dist/provision/ProvisionPodCreator.jsonld +31 -0
  442. package/dist/provision/ServiceAccessTokenCodec.d.ts +45 -0
  443. package/dist/provision/ServiceAccessTokenCodec.js +86 -0
  444. package/dist/provision/ServiceAccessTokenCodec.js.map +1 -0
  445. package/dist/runtime/GatewayAdminProxyAuth.d.ts +29 -0
  446. package/dist/runtime/GatewayAdminProxyAuth.js +108 -0
  447. package/dist/runtime/GatewayAdminProxyAuth.js.map +1 -0
  448. package/dist/runtime/Proxy.d.ts +10 -0
  449. package/dist/runtime/Proxy.js +64 -6
  450. package/dist/runtime/Proxy.js.map +1 -1
  451. package/dist/runtime/XpodRuntime.js +1 -0
  452. package/dist/runtime/XpodRuntime.js.map +1 -1
  453. package/dist/runtime/bootstrap.d.ts +1 -0
  454. package/dist/runtime/bootstrap.js +29 -0
  455. package/dist/runtime/bootstrap.js.map +1 -1
  456. package/dist/runtime/css-process.d.ts +1 -0
  457. package/dist/runtime/css-process.js +1 -0
  458. package/dist/runtime/css-process.js.map +1 -1
  459. package/dist/runtime/index.d.ts +1 -0
  460. package/dist/runtime/index.js +3 -1
  461. package/dist/runtime/index.js.map +1 -1
  462. package/dist/runtime/lifecycle.d.ts +3 -1
  463. package/dist/runtime/lifecycle.js +3 -1
  464. package/dist/runtime/lifecycle.js.map +1 -1
  465. package/dist/runtime/runner/node/NodeGatewayRuntimeRunner.js +2 -0
  466. package/dist/runtime/runner/node/NodeGatewayRuntimeRunner.js.map +1 -1
  467. package/dist/runtime/runner/types.d.ts +3 -0
  468. package/dist/runtime/runner/types.js.map +1 -1
  469. package/dist/runtime/runtime-types.d.ts +2 -0
  470. package/dist/runtime/runtime-types.js.map +1 -1
  471. package/dist/runtime/safe-env.d.ts +15 -0
  472. package/dist/runtime/safe-env.js +109 -0
  473. package/dist/runtime/safe-env.js.map +1 -0
  474. package/dist/security/index.d.ts +1 -0
  475. package/dist/security/index.js +18 -0
  476. package/dist/security/index.js.map +1 -0
  477. package/dist/security/secret-cell/DeploymentRootKeyProvider.d.ts +17 -0
  478. package/dist/security/secret-cell/DeploymentRootKeyProvider.js +61 -0
  479. package/dist/security/secret-cell/DeploymentRootKeyProvider.js.map +1 -0
  480. package/dist/security/secret-cell/DeploymentRootKeyProvider.jsonld +124 -0
  481. package/dist/security/secret-cell/SecretCellVault.d.ts +55 -0
  482. package/dist/security/secret-cell/SecretCellVault.js +242 -0
  483. package/dist/security/secret-cell/SecretCellVault.js.map +1 -0
  484. package/dist/security/secret-cell/SecretCellVault.jsonld +207 -0
  485. package/dist/security/secret-cell/index.d.ts +2 -0
  486. package/dist/security/secret-cell/index.js +11 -0
  487. package/dist/security/secret-cell/index.js.map +1 -0
  488. package/dist/solidfs/CompositeSolidFsSyncer.d.ts +18 -0
  489. package/dist/solidfs/CompositeSolidFsSyncer.js +32 -0
  490. package/dist/solidfs/CompositeSolidFsSyncer.js.map +1 -0
  491. package/dist/solidfs/LocalSolidFS.js +25 -1
  492. package/dist/solidfs/LocalSolidFS.js.map +1 -1
  493. package/dist/solidfs/RdfIndexSolidFsSyncer.d.ts +41 -2
  494. package/dist/solidfs/RdfIndexSolidFsSyncer.js +331 -21
  495. package/dist/solidfs/RdfIndexSolidFsSyncer.js.map +1 -1
  496. package/dist/solidfs/SolidFsMetaNotes.d.ts +25 -0
  497. package/dist/solidfs/SolidFsMetaNotes.js +103 -0
  498. package/dist/solidfs/SolidFsMetaNotes.js.map +1 -0
  499. package/dist/solidfs/SolidFsSyncJournal.d.ts +2 -2
  500. package/dist/solidfs/SolidFsSyncJournal.js +9 -4
  501. package/dist/solidfs/SolidFsSyncJournal.js.map +1 -1
  502. package/dist/solidfs/SolidFsSyncJournal.jsonld +119 -0
  503. package/dist/solidfs/WorkspacePrompt.d.ts +13 -0
  504. package/dist/solidfs/WorkspacePrompt.js +42 -0
  505. package/dist/solidfs/WorkspacePrompt.js.map +1 -0
  506. package/dist/solidfs/index.d.ts +3 -0
  507. package/dist/solidfs/index.js +3 -0
  508. package/dist/solidfs/index.js.map +1 -1
  509. package/dist/solidfs/types.d.ts +12 -2
  510. package/dist/solidfs/types.js.map +1 -1
  511. package/dist/storage/accessors/MixDataAccessor.d.ts +36 -4
  512. package/dist/storage/accessors/MixDataAccessor.js +222 -23
  513. package/dist/storage/accessors/MixDataAccessor.js.map +1 -1
  514. package/dist/storage/accessors/MixDataAccessor.jsonld +89 -0
  515. package/dist/storage/accessors/SolidRdfDataAccessor.d.ts +6 -1
  516. package/dist/storage/accessors/SolidRdfDataAccessor.js +35 -0
  517. package/dist/storage/accessors/SolidRdfDataAccessor.js.map +1 -1
  518. package/dist/storage/accessors/SolidRdfDataAccessor.jsonld +20 -0
  519. package/dist/storage/database/PostgresPoolManager.d.ts +1 -0
  520. package/dist/storage/database/PostgresPoolManager.js +2 -2
  521. package/dist/storage/database/PostgresPoolManager.js.map +1 -1
  522. package/dist/storage/locking/UrlAwareRedisLocker.d.ts +2 -0
  523. package/dist/storage/locking/UrlAwareRedisLocker.js +65 -0
  524. package/dist/storage/locking/UrlAwareRedisLocker.js.map +1 -1
  525. package/dist/storage/locking/UrlAwareRedisLocker.jsonld +19 -0
  526. package/dist/storage/rdf/PostgresRdfEngine.d.ts +286 -9
  527. package/dist/storage/rdf/PostgresRdfEngine.js +10773 -2084
  528. package/dist/storage/rdf/PostgresRdfEngine.js.map +1 -1
  529. package/dist/storage/rdf/PostgresRdfEngine.jsonld +1693 -89
  530. package/dist/storage/rdf/PostgresRdfSqlExecutor.d.ts +24 -0
  531. package/dist/storage/rdf/PostgresRdfSqlExecutor.js +131 -0
  532. package/dist/storage/rdf/PostgresRdfSqlExecutor.js.map +1 -0
  533. package/dist/storage/rdf/PostgresRdfTextIndex.d.ts +54 -0
  534. package/dist/storage/rdf/PostgresRdfTextIndex.js +1255 -0
  535. package/dist/storage/rdf/PostgresRdfTextIndex.js.map +1 -0
  536. package/dist/storage/rdf/PostgresRdfTextIndex.jsonld +487 -0
  537. package/dist/storage/rdf/PostgresRdfVectorIndex.d.ts +46 -0
  538. package/dist/storage/rdf/PostgresRdfVectorIndex.js +1165 -0
  539. package/dist/storage/rdf/PostgresRdfVectorIndex.js.map +1 -0
  540. package/dist/storage/rdf/PostgresRdfVectorIndex.jsonld +423 -0
  541. package/dist/storage/rdf/Rdf3xIndex.d.ts +14 -1
  542. package/dist/storage/rdf/Rdf3xIndex.js +286 -2
  543. package/dist/storage/rdf/Rdf3xIndex.js.map +1 -1
  544. package/dist/storage/rdf/Rdf3xIndex.jsonld +36 -0
  545. package/dist/storage/rdf/Rdf3xSchema.d.ts +5 -1
  546. package/dist/storage/rdf/Rdf3xSchema.js +17 -3
  547. package/dist/storage/rdf/Rdf3xSchema.js.map +1 -1
  548. package/dist/storage/rdf/RdfAccessScope.d.ts +22 -0
  549. package/dist/storage/rdf/RdfAccessScope.js +345 -0
  550. package/dist/storage/rdf/RdfAccessScope.js.map +1 -0
  551. package/dist/storage/rdf/RdfAccessScope.jsonld +45 -0
  552. package/dist/storage/rdf/RdfFusionRankPlan.d.ts +2 -0
  553. package/dist/storage/rdf/RdfFusionRankPlan.js +186 -0
  554. package/dist/storage/rdf/RdfFusionRankPlan.js.map +1 -0
  555. package/dist/storage/rdf/RdfJoinShape.d.ts +8 -0
  556. package/dist/storage/rdf/RdfJoinShape.js +31 -0
  557. package/dist/storage/rdf/RdfJoinShape.js.map +1 -0
  558. package/dist/storage/rdf/RdfQuadIndex.d.ts +5 -2
  559. package/dist/storage/rdf/RdfQuadIndex.js +94 -6
  560. package/dist/storage/rdf/RdfQuadIndex.js.map +1 -1
  561. package/dist/storage/rdf/RdfQuadIndex.jsonld +12 -0
  562. package/dist/storage/rdf/RdfQueryExecutor.d.ts +3 -4
  563. package/dist/storage/rdf/RdfQueryExecutor.js +235 -8
  564. package/dist/storage/rdf/RdfQueryExecutor.js.map +1 -1
  565. package/dist/storage/rdf/RdfSearchSourceFilter.d.ts +10 -0
  566. package/dist/storage/rdf/RdfSearchSourceFilter.js +83 -0
  567. package/dist/storage/rdf/RdfSearchSourceFilter.js.map +1 -0
  568. package/dist/storage/rdf/RdfSparqlAdapter.d.ts +27 -1
  569. package/dist/storage/rdf/RdfSparqlAdapter.js +265 -3
  570. package/dist/storage/rdf/RdfSparqlAdapter.js.map +1 -1
  571. package/dist/storage/rdf/RdfSparqlAdapter.jsonld +8 -0
  572. package/dist/storage/rdf/RdfTermDictionary.d.ts +7 -1
  573. package/dist/storage/rdf/RdfTermDictionary.js +139 -0
  574. package/dist/storage/rdf/RdfTermDictionary.js.map +1 -1
  575. package/dist/storage/rdf/RdfTermDictionary.jsonld +4 -0
  576. package/dist/storage/rdf/RdfTextIndex.d.ts +45 -2
  577. package/dist/storage/rdf/RdfTextIndex.js +810 -114
  578. package/dist/storage/rdf/RdfTextIndex.js.map +1 -1
  579. package/dist/storage/rdf/RdfTextIndex.jsonld +193 -0
  580. package/dist/storage/rdf/RdfTextProjection.d.ts +10 -0
  581. package/dist/storage/rdf/RdfTextProjection.js +258 -0
  582. package/dist/storage/rdf/RdfTextProjection.js.map +1 -0
  583. package/dist/storage/rdf/RdfVectorIndex.d.ts +30 -2
  584. package/dist/storage/rdf/RdfVectorIndex.js +461 -38
  585. package/dist/storage/rdf/RdfVectorIndex.js.map +1 -1
  586. package/dist/storage/rdf/RdfVectorIndex.jsonld +163 -0
  587. package/dist/storage/rdf/SolidRdfEngine.d.ts +12 -9
  588. package/dist/storage/rdf/SolidRdfEngine.js +48 -22
  589. package/dist/storage/rdf/SolidRdfEngine.js.map +1 -1
  590. package/dist/storage/rdf/SolidRdfEngine.jsonld +33 -43
  591. package/dist/storage/rdf/SolidRdfSparqlEngine.d.ts +19 -8
  592. package/dist/storage/rdf/SolidRdfSparqlEngine.js +674 -44
  593. package/dist/storage/rdf/SolidRdfSparqlEngine.js.map +1 -1
  594. package/dist/storage/rdf/SolidRdfSparqlEngine.jsonld +51 -0
  595. package/dist/storage/rdf/index.d.ts +9 -5
  596. package/dist/storage/rdf/index.js +42 -1
  597. package/dist/storage/rdf/index.js.map +1 -1
  598. package/dist/storage/rdf/models-benchmark.d.ts +264 -2
  599. package/dist/storage/rdf/models-benchmark.js +4207 -155
  600. package/dist/storage/rdf/models-benchmark.js.map +1 -1
  601. package/dist/storage/rdf/types.d.ts +833 -4
  602. package/dist/storage/rdf/types.js.map +1 -1
  603. package/dist/storage/rdf/types.jsonld +348 -0
  604. package/dist/storage/sparql/CompatibilitySparqlEngine.d.ts +14 -13
  605. package/dist/storage/sparql/CompatibilitySparqlEngine.js +24 -24
  606. package/dist/storage/sparql/CompatibilitySparqlEngine.js.map +1 -1
  607. package/dist/storage/sparql/CompatibilitySparqlEngineImpl.d.ts +14 -13
  608. package/dist/storage/sparql/CompatibilitySparqlEngineImpl.js +30 -18
  609. package/dist/storage/sparql/CompatibilitySparqlEngineImpl.js.map +1 -1
  610. package/dist/storage/sparql/SubgraphQueryEngine.d.ts +21 -12
  611. package/dist/storage/sparql/SubgraphQueryEngine.js +12 -12
  612. package/dist/storage/sparql/SubgraphQueryEngine.js.map +1 -1
  613. package/dist/terminal/sandbox/MacOSSandbox.js +2 -1
  614. package/dist/terminal/sandbox/MacOSSandbox.js.map +1 -1
  615. package/dist/terminal/sandbox/index.js +2 -1
  616. package/dist/terminal/sandbox/index.js.map +1 -1
  617. package/dist/test-utils/no-auth-xpod.js +3 -0
  618. package/dist/test-utils/no-auth-xpod.js.map +1 -1
  619. package/dist/tunnel/LocalTunnelProvider.d.ts +3 -0
  620. package/dist/tunnel/LocalTunnelProvider.js +17 -1
  621. package/dist/tunnel/LocalTunnelProvider.js.map +1 -1
  622. package/dist/tunnel/LocalTunnelProvider.jsonld +23 -0
  623. package/dist/tunnel/SakuraFrpTunnelProvider.d.ts +3 -0
  624. package/dist/tunnel/SakuraFrpTunnelProvider.js +18 -2
  625. package/dist/tunnel/SakuraFrpTunnelProvider.js.map +1 -1
  626. package/dist/tunnel/TunnelProfiles.d.ts +22 -0
  627. package/dist/tunnel/TunnelProfiles.js +208 -0
  628. package/dist/tunnel/TunnelProfiles.js.map +1 -0
  629. package/dist/tunnel/index.d.ts +2 -0
  630. package/dist/tunnel/index.js +4 -1
  631. package/dist/tunnel/index.js.map +1 -1
  632. package/dist/util/identifiers/ClusterIdentifierStrategy.d.ts +3 -0
  633. package/dist/util/identifiers/ClusterIdentifierStrategy.js +18 -2
  634. package/dist/util/identifiers/ClusterIdentifierStrategy.js.map +1 -1
  635. package/dist/util/identifiers/ClusterIdentifierStrategy.jsonld +5 -1
  636. package/node_modules/@undefineds.co/ai-connection/dist/AiClientConfigurationSection.d.ts +55 -0
  637. package/node_modules/@undefineds.co/ai-connection/dist/AiClientConfigurationSection.js +167 -0
  638. package/node_modules/@undefineds.co/ai-connection/dist/AiConnectionHeader.d.ts +3 -0
  639. package/node_modules/@undefineds.co/ai-connection/dist/AiConnectionHeader.js +8 -0
  640. package/node_modules/@undefineds.co/ai-connection/dist/AiConnectionList.d.ts +4 -0
  641. package/node_modules/@undefineds.co/ai-connection/dist/AiConnectionList.js +36 -0
  642. package/node_modules/@undefineds.co/ai-connection/dist/AiConnectionMain.d.ts +4 -0
  643. package/node_modules/@undefineds.co/ai-connection/dist/AiConnectionMain.js +37 -0
  644. package/node_modules/@undefineds.co/ai-connection/dist/AiConnectionMainHeader.d.ts +3 -0
  645. package/node_modules/@undefineds.co/ai-connection/dist/AiConnectionMainHeader.js +7 -0
  646. package/node_modules/@undefineds.co/ai-connection/dist/AiConnectionPanel.d.ts +14 -0
  647. package/node_modules/@undefineds.co/ai-connection/dist/AiConnectionPanel.js +333 -0
  648. package/node_modules/@undefineds.co/ai-connection/dist/AiProviderCard.d.ts +22 -0
  649. package/node_modules/@undefineds.co/ai-connection/dist/AiProviderCard.js +43 -0
  650. package/node_modules/@undefineds.co/ai-connection/dist/AiQuotaCard.d.ts +8 -0
  651. package/node_modules/@undefineds.co/ai-connection/dist/AiQuotaCard.js +6 -0
  652. package/node_modules/@undefineds.co/ai-connection/dist/ai-connection-client.d.ts +120 -0
  653. package/node_modules/@undefineds.co/ai-connection/dist/ai-connection-client.js +414 -0
  654. package/node_modules/@undefineds.co/ai-connection/dist/client-config/base-adapter.d.ts +32 -0
  655. package/node_modules/@undefineds.co/ai-connection/dist/client-config/base-adapter.js +212 -0
  656. package/node_modules/@undefineds.co/ai-connection/dist/client-config/codex.d.ts +14 -0
  657. package/node_modules/@undefineds.co/ai-connection/dist/client-config/codex.js +90 -0
  658. package/node_modules/@undefineds.co/ai-connection/dist/client-config/index.cjs +668 -0
  659. package/node_modules/@undefineds.co/ai-connection/dist/client-config/index.d.ts +6 -0
  660. package/node_modules/@undefineds.co/ai-connection/dist/client-config/index.js +6 -0
  661. package/node_modules/@undefineds.co/ai-connection/dist/client-config/json-env-adapter.d.ts +21 -0
  662. package/node_modules/@undefineds.co/ai-connection/dist/client-config/json-env-adapter.js +82 -0
  663. package/node_modules/@undefineds.co/ai-connection/dist/client-config/pi.d.ts +13 -0
  664. package/node_modules/@undefineds.co/ai-connection/dist/client-config/pi.js +83 -0
  665. package/node_modules/@undefineds.co/ai-connection/dist/client-config/transaction.d.ts +17 -0
  666. package/node_modules/@undefineds.co/ai-connection/dist/client-config/transaction.js +153 -0
  667. package/node_modules/@undefineds.co/ai-connection/dist/client-config/types.d.ts +40 -0
  668. package/node_modules/@undefineds.co/ai-connection/dist/client-config/types.js +1 -0
  669. package/node_modules/@undefineds.co/ai-connection/dist/controller.d.ts +42 -0
  670. package/node_modules/@undefineds.co/ai-connection/dist/controller.js +289 -0
  671. package/node_modules/@undefineds.co/ai-connection/dist/index.d.ts +16 -0
  672. package/node_modules/@undefineds.co/ai-connection/dist/index.js +41 -0
  673. package/node_modules/@undefineds.co/ai-connection/dist/manifest.d.ts +1 -0
  674. package/node_modules/@undefineds.co/ai-connection/dist/manifest.js +18 -0
  675. package/node_modules/@undefineds.co/ai-connection/dist/service-access.d.ts +3 -0
  676. package/node_modules/@undefineds.co/ai-connection/dist/service-access.js +133 -0
  677. package/node_modules/@undefineds.co/ai-connection/package.json +50 -0
  678. package/node_modules/@undefineds.co/extension-sdk/README.md +299 -0
  679. package/node_modules/@undefineds.co/extension-sdk/dist/index.d.ts +5 -0
  680. package/node_modules/@undefineds.co/extension-sdk/dist/index.js +5 -0
  681. package/node_modules/@undefineds.co/extension-sdk/dist/layout.d.ts +16 -0
  682. package/node_modules/@undefineds.co/extension-sdk/dist/layout.js +36 -0
  683. package/node_modules/@undefineds.co/extension-sdk/dist/manifest.d.ts +27 -0
  684. package/node_modules/@undefineds.co/extension-sdk/dist/manifest.js +79 -0
  685. package/node_modules/@undefineds.co/extension-sdk/dist/react/app-layout.d.ts +7 -0
  686. package/node_modules/@undefineds.co/extension-sdk/dist/react/app-layout.js +8 -0
  687. package/node_modules/@undefineds.co/extension-sdk/dist/react/auth-boundary.d.ts +27 -0
  688. package/node_modules/@undefineds.co/extension-sdk/dist/react/auth-boundary.js +49 -0
  689. package/node_modules/@undefineds.co/extension-sdk/dist/react/layout-context.d.ts +11 -0
  690. package/node_modules/@undefineds.co/extension-sdk/dist/react/layout-context.js +9 -0
  691. package/node_modules/@undefineds.co/extension-sdk/dist/react/workspace-layout.d.ts +38 -0
  692. package/node_modules/@undefineds.co/extension-sdk/dist/react/workspace-layout.js +132 -0
  693. package/node_modules/@undefineds.co/extension-sdk/dist/react.d.ts +12 -0
  694. package/node_modules/@undefineds.co/extension-sdk/dist/react.js +19 -0
  695. package/node_modules/@undefineds.co/extension-sdk/dist/testing.d.ts +7 -0
  696. package/node_modules/@undefineds.co/extension-sdk/dist/testing.js +27 -0
  697. package/node_modules/@undefineds.co/extension-sdk/dist/web.d.ts +225 -0
  698. package/node_modules/@undefineds.co/extension-sdk/dist/web.js +142 -0
  699. package/node_modules/@undefineds.co/extension-sdk/package.json +49 -0
  700. package/node_modules/@undefineds.co/extensions/README.md +101 -0
  701. package/node_modules/@undefineds.co/extensions/dist/adapters/langchain.d.ts +25 -0
  702. package/node_modules/@undefineds.co/extensions/dist/adapters/langchain.d.ts.map +1 -0
  703. package/node_modules/@undefineds.co/extensions/dist/adapters/langchain.js +45 -0
  704. package/node_modules/@undefineds.co/extensions/dist/adapters/langchain.js.map +1 -0
  705. package/node_modules/@undefineds.co/extensions/dist/adapters/llamaindex.d.ts +31 -0
  706. package/node_modules/@undefineds.co/extensions/dist/adapters/llamaindex.d.ts.map +1 -0
  707. package/node_modules/@undefineds.co/extensions/dist/adapters/llamaindex.js +50 -0
  708. package/node_modules/@undefineds.co/extensions/dist/adapters/llamaindex.js.map +1 -0
  709. package/node_modules/@undefineds.co/extensions/dist/index.d.ts +7 -0
  710. package/node_modules/@undefineds.co/extensions/dist/index.d.ts.map +1 -0
  711. package/node_modules/@undefineds.co/extensions/dist/index.js +7 -0
  712. package/node_modules/@undefineds.co/extensions/dist/index.js.map +1 -0
  713. package/node_modules/@undefineds.co/extensions/dist/paddleocr.d.ts +16 -0
  714. package/node_modules/@undefineds.co/extensions/dist/paddleocr.d.ts.map +1 -0
  715. package/node_modules/@undefineds.co/extensions/dist/paddleocr.js +267 -0
  716. package/node_modules/@undefineds.co/extensions/dist/paddleocr.js.map +1 -0
  717. package/node_modules/@undefineds.co/extensions/dist/reader.d.ts +18 -0
  718. package/node_modules/@undefineds.co/extensions/dist/reader.d.ts.map +1 -0
  719. package/node_modules/@undefineds.co/extensions/dist/reader.js +39 -0
  720. package/node_modules/@undefineds.co/extensions/dist/reader.js.map +1 -0
  721. package/node_modules/@undefineds.co/extensions/dist/registry.d.ts +16 -0
  722. package/node_modules/@undefineds.co/extensions/dist/registry.d.ts.map +1 -0
  723. package/node_modules/@undefineds.co/extensions/dist/registry.js +97 -0
  724. package/node_modules/@undefineds.co/extensions/dist/registry.js.map +1 -0
  725. package/node_modules/@undefineds.co/extensions/dist/types.d.ts +141 -0
  726. package/node_modules/@undefineds.co/extensions/dist/types.d.ts.map +1 -0
  727. package/node_modules/@undefineds.co/extensions/dist/types.js +2 -0
  728. package/node_modules/@undefineds.co/extensions/dist/types.js.map +1 -0
  729. package/node_modules/@undefineds.co/extensions/package.json +38 -0
  730. package/node_modules/@undefineds.co/shared-ui/dist/badge.d.ts +8 -0
  731. package/node_modules/@undefineds.co/shared-ui/dist/badge.js +17 -0
  732. package/node_modules/@undefineds.co/shared-ui/dist/button.d.ts +10 -0
  733. package/node_modules/@undefineds.co/shared-ui/dist/button.js +30 -0
  734. package/node_modules/@undefineds.co/shared-ui/dist/card.d.ts +7 -0
  735. package/node_modules/@undefineds.co/shared-ui/dist/card.js +15 -0
  736. package/node_modules/@undefineds.co/shared-ui/dist/index.d.ts +6 -0
  737. package/node_modules/@undefineds.co/shared-ui/dist/index.js +6 -0
  738. package/node_modules/@undefineds.co/shared-ui/dist/input.d.ts +4 -0
  739. package/node_modules/@undefineds.co/shared-ui/dist/input.js +5 -0
  740. package/node_modules/@undefineds.co/shared-ui/dist/theme.css +121 -0
  741. package/node_modules/@undefineds.co/shared-ui/dist/utils.d.ts +2 -0
  742. package/node_modules/@undefineds.co/shared-ui/dist/utils.js +5 -0
  743. package/node_modules/@undefineds.co/shared-ui/dist/workspace.d.ts +23 -0
  744. package/node_modules/@undefineds.co/shared-ui/dist/workspace.js +38 -0
  745. package/node_modules/@undefineds.co/shared-ui/package.json +39 -0
  746. package/node_modules/@undefineds.co/solid-sdk/dist/index.d.ts +3 -0
  747. package/node_modules/@undefineds.co/solid-sdk/dist/index.js +3 -0
  748. package/node_modules/@undefineds.co/solid-sdk/dist/pod-runtime.d.ts +45 -0
  749. package/node_modules/@undefineds.co/solid-sdk/dist/pod-runtime.js +147 -0
  750. package/node_modules/@undefineds.co/solid-sdk/dist/react.d.ts +15 -0
  751. package/node_modules/@undefineds.co/solid-sdk/dist/react.js +15 -0
  752. package/node_modules/@undefineds.co/solid-sdk/dist/session.d.ts +42 -0
  753. package/node_modules/@undefineds.co/solid-sdk/dist/session.js +127 -0
  754. package/node_modules/@undefineds.co/solid-sdk/package.json +45 -0
  755. package/package.json +31 -13
  756. package/static/app/assets/index-BoYHJ6si.js +230 -0
  757. package/static/app/assets/inrupt-smoke.js +2 -2
  758. package/static/app/assets/main.css +1 -1
  759. package/static/app/assets/main.js +9 -9
  760. package/static/dashboard/assets/NetworkPage-Brt79fuQ.js +2 -0
  761. package/static/dashboard/assets/PaneListHeader-57nvMwH6.js +1 -0
  762. package/static/dashboard/assets/PodPage-CM6do1vB.js +2 -0
  763. package/static/dashboard/assets/ServicesPage-BUNxGJRz.js +1 -0
  764. package/static/dashboard/assets/card-B9Zjf_2p.js +1 -0
  765. package/static/dashboard/assets/dashboard-8C6o666W.js +305 -0
  766. package/static/dashboard/assets/dashboard-CSdewNeA.css +1 -0
  767. package/static/dashboard/assets/database-DPh9wDY9.js +1 -0
  768. package/static/dashboard/assets/external-link-VbMQvVMz.js +1 -0
  769. package/static/dashboard/assets/index-RfiFckzb.js +51 -0
  770. package/static/dashboard/assets/refresh-cw-BxVxNxNr.js +1 -0
  771. package/static/dashboard/assets/services-status-context-DKmJ7ISr.js +1 -0
  772. package/static/dashboard/dashboard.html +2 -2
  773. package/static/settings/assets/ModelsPage-D_IH7AH3.js +1 -0
  774. package/static/settings/assets/PaneListHeader-Bgaze006.js +1 -0
  775. package/static/settings/assets/PodPage-Cy1VNObw.js +2 -0
  776. package/static/settings/assets/ServicesPage-BsFaxVWC.js +1 -0
  777. package/static/settings/assets/SettingsPage-UafNWE_p.js +48 -0
  778. package/static/settings/assets/card-B_bXSIn-.js +1 -0
  779. package/static/settings/assets/services-status-context-DiX-AbrP.js +1 -0
  780. package/static/settings/assets/settings-B30oMfZq.js +305 -0
  781. package/static/settings/assets/settings-CSdewNeA.css +1 -0
  782. package/static/settings/assets/workspace-layout-Dv1Yn9Ci.js +1 -0
  783. package/static/settings/auth.html +21 -0
  784. package/static/settings/reachability.html +221 -0
  785. package/static/settings/reachability.svg +7 -0
  786. package/static/settings/reachability.webmanifest +18 -0
  787. package/static/settings/settings.html +13 -0
  788. package/static/settings/signal-pod.html +293 -0
  789. package/static/settings/vite.svg +1 -0
  790. package/dist/api/service/ai-gateway-transport.d.ts +0 -25
  791. package/dist/api/service/ai-gateway-transport.js +0 -136
  792. package/dist/api/service/ai-gateway-transport.js.map +0 -1
  793. package/dist/api/service/chat-protocol-adapters.d.ts +0 -5
  794. package/dist/api/service/chat-protocol-adapters.js +0 -146
  795. package/dist/api/service/chat-protocol-adapters.js.map +0 -1
  796. package/dist/api/service/chat-routing.d.ts +0 -8
  797. package/dist/api/service/chat-routing.js +0 -16
  798. package/dist/api/service/chat-routing.js.map +0 -1
  799. package/dist/api/service/platform-ai-config.d.ts +0 -10
  800. package/dist/api/service/platform-ai-config.js +0 -76
  801. package/dist/api/service/platform-ai-config.js.map +0 -1
  802. package/dist/document/DocumentParser.js.map +0 -1
  803. package/dist/document/JinaDocumentParser.js.map +0 -1
  804. package/static/app/assets/index-C1yksyT4.js +0 -171
  805. package/static/dashboard/assets/dashboard-BssaVKTn.css +0 -1
  806. package/static/dashboard/assets/dashboard-Ckuadl3C.js +0 -54
@@ -1,14 +1,30 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.rdfModelsQueryBenchmarkCases = exports.rdfModelsBenchmarkCases = exports.RDF_MODELS_SYNTHETIC_MESSAGE_QUADS = void 0;
3
+ exports.rdfModelsExtremeQueryBenchmarkCases = exports.rdfModelsExtremeBenchmarkCases = exports.rdfModelsPostgresQueryBenchmarkCases = exports.rdfModelsPostgresMaterializedQueryBenchmarkCases = exports.rdfModelsSearchFusionQueryBenchmarkCases = exports.rdfModelsQueryBenchmarkCases = exports.rdfModelsBenchmarkCases = exports.RDF_MODELS_BENCHMARK_POD = exports.RDF_MODELS_SEARCH_FUSION_BROAD_SOURCE_COUNT = exports.RDF_MODELS_NATIVE_STRESS_MESSAGE_COUNT = exports.RDF_MODELS_NATIVE_STRESS_MESSAGE_QUADS = exports.RDF_MODELS_SYNTHETIC_MESSAGE_QUADS = void 0;
4
+ exports.rdfModelsBenchmarkCasesForProfile = rdfModelsBenchmarkCasesForProfile;
5
+ exports.rdfModelsQueryBenchmarkCasesForProfile = rdfModelsQueryBenchmarkCasesForProfile;
6
+ exports.rdfModelsPostgresQueryBenchmarkCasesForProfile = rdfModelsPostgresQueryBenchmarkCasesForProfile;
4
7
  exports.rdfModelsBenchmarkCaseNames = rdfModelsBenchmarkCaseNames;
5
8
  exports.rdfModelsQueryBenchmarkCaseNames = rdfModelsQueryBenchmarkCaseNames;
9
+ exports.rdfModelsPostgresQueryBenchmarkCaseNames = rdfModelsPostgresQueryBenchmarkCaseNames;
10
+ exports.rdfModelsPostgresMaterializedQueryBenchmarkCaseNames = rdfModelsPostgresMaterializedQueryBenchmarkCaseNames;
11
+ exports.rdfModelsSearchFusionQueryBenchmarkCaseNames = rdfModelsSearchFusionQueryBenchmarkCaseNames;
12
+ exports.rdfModelsExtremeBenchmarkCaseNames = rdfModelsExtremeBenchmarkCaseNames;
13
+ exports.rdfModelsExtremeQueryBenchmarkCaseNames = rdfModelsExtremeQueryBenchmarkCaseNames;
6
14
  exports.rdfModelsBenchmarkScaleTargetQuads = rdfModelsBenchmarkScaleTargetQuads;
7
15
  exports.rdfModelsBenchmarkSyntheticPodCount = rdfModelsBenchmarkSyntheticPodCount;
8
16
  exports.estimateRdfModelsSyntheticQuadCount = estimateRdfModelsSyntheticQuadCount;
17
+ exports.syntheticMessagesForRdfModelsTargetQuads = syntheticMessagesForRdfModelsTargetQuads;
9
18
  exports.defaultSyntheticMessagesForRdfModelsScale = defaultSyntheticMessagesForRdfModelsScale;
10
19
  exports.rdfModelsBenchmarkScaleSatisfied = rdfModelsBenchmarkScaleSatisfied;
20
+ exports.rdfModelsBenchmarkTargetSatisfied = rdfModelsBenchmarkTargetSatisfied;
21
+ exports.buildRdfModelsBenchmarkSeed = buildRdfModelsBenchmarkSeed;
22
+ exports.rdfModelsBenchmarkProfileRequiresSearchFusion = rdfModelsBenchmarkProfileRequiresSearchFusion;
23
+ exports.rdfModelsSearchFusionBroadSourceCountForScale = rdfModelsSearchFusionBroadSourceCountForScale;
24
+ exports.seedRdfModelsSearchFusionIndexes = seedRdfModelsSearchFusionIndexes;
11
25
  exports.runRdfModelsBenchmark = runRdfModelsBenchmark;
26
+ exports.runRdfModelsPostgresBenchmark = runRdfModelsPostgresBenchmark;
27
+ exports.postgresServingRegressionFailures = postgresServingRegressionFailures;
12
28
  exports.runRdfModelsShadowBenchmark = runRdfModelsShadowBenchmark;
13
29
  exports.runRdfModelsRdf3xShadowBenchmark = runRdfModelsRdf3xShadowBenchmark;
14
30
  const node_crypto_1 = require("node:crypto");
@@ -17,8 +33,16 @@ const n3_2 = require("n3");
17
33
  const types_1 = require("../quint/types");
18
34
  const RdfShadowComparator_1 = require("./RdfShadowComparator");
19
35
  const RdfTermSemantics_1 = require("./RdfTermSemantics");
20
- const { namedNode, literal } = n3_1.DataFactory;
21
- exports.RDF_MODELS_SYNTHETIC_MESSAGE_QUADS = 4;
36
+ const { namedNode, literal, quad } = n3_1.DataFactory;
37
+ exports.RDF_MODELS_SYNTHETIC_MESSAGE_QUADS = 9;
38
+ exports.RDF_MODELS_NATIVE_STRESS_MESSAGE_QUADS = 9;
39
+ exports.RDF_MODELS_NATIVE_STRESS_MESSAGE_COUNT = 1024;
40
+ exports.RDF_MODELS_SEARCH_FUSION_BROAD_SOURCE_COUNT = 32;
41
+ const RDF_MODELS_SEARCH_FUSION_BROAD_SOURCE_COUNTS = {
42
+ small: exports.RDF_MODELS_SEARCH_FUSION_BROAD_SOURCE_COUNT,
43
+ medium: 256,
44
+ large: 4096,
45
+ };
22
46
  const RDF_MODELS_SCALE_TARGET_QUADS = {
23
47
  small: 48,
24
48
  medium: 10_000,
@@ -29,20 +53,54 @@ const RDF_MODELS_SYNTHETIC_POD_COUNTS = {
29
53
  medium: 1,
30
54
  large: 4,
31
55
  };
56
+ exports.RDF_MODELS_BENCHMARK_POD = 'https://pod.example/alice';
57
+ const DATA = `${exports.RDF_MODELS_BENCHMARK_POD}/.data`;
58
+ const NATIVE_STRESS_GRAPH = `${DATA}/chat/default/2026/05/18/native-stress.ttl`;
59
+ const SETTINGS = `${exports.RDF_MODELS_BENCHMARK_POD}/settings`;
60
+ const WORKSPACE = 'file://macbook.local/Users/alice/project/';
61
+ const RDF_MODELS_SEARCH_VECTOR_MODEL = 'xpod-benchmark-embedding-v1';
32
62
  const RDF_TYPE = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type';
33
63
  const DCT_CREATED = 'http://purl.org/dc/terms/created';
34
64
  const DCT_MODIFIED = 'http://purl.org/dc/terms/modified';
65
+ const DCT_DESCRIPTION = 'http://purl.org/dc/terms/description';
35
66
  const DCT_TITLE = 'http://purl.org/dc/terms/title';
67
+ const DCT_TYPE = 'http://purl.org/dc/terms/type';
68
+ const DCT_CREATOR = 'http://purl.org/dc/terms/creator';
36
69
  const SIOC_CONTENT = 'http://rdfs.org/sioc/ns#content';
37
70
  const SIOC_HAS_MEMBER = 'http://rdfs.org/sioc/ns#has_member';
71
+ const SIOC_HAS_CONTAINER = 'http://rdfs.org/sioc/ns#has_container';
72
+ const SIOC_HAS_PARENT = 'http://rdfs.org/sioc/ns#has_parent';
38
73
  const UDFS = 'https://undefineds.co/ns#';
74
+ const XPOD_AI = 'https://vocab.xpod.dev/ai#';
75
+ const XPOD_CREDENTIAL = 'https://vocab.xpod.dev/credential#';
39
76
  const MEETING = 'http://www.w3.org/ns/pim/meeting#';
40
77
  const SIOC = 'http://rdfs.org/sioc/ns#';
78
+ const WF_MESSAGE = 'http://www.w3.org/2005/01/wf/flow-1.0#message';
41
79
  const FOAF_AGENT = 'http://xmlns.com/foaf/0.1/Agent';
80
+ const FOAF_PERSON = 'http://xmlns.com/foaf/0.1/Person';
81
+ const FOAF_MAKER = 'http://xmlns.com/foaf/0.1/maker';
82
+ const FOAF_PRIMARY_TOPIC = 'http://xmlns.com/foaf/0.1/primaryTopic';
42
83
  const VCARD_INDIVIDUAL = 'http://www.w3.org/2006/vcard/ns#Individual';
84
+ const VCARD_FN = 'http://www.w3.org/2006/vcard/ns#fn';
85
+ const LDP_INBOX = 'http://www.w3.org/ns/ldp#inbox';
86
+ const SCHEMA_PROPERTY_VALUE = 'http://schema.org/PropertyValue';
43
87
  const SCHEMA_CREATIVE_WORK = 'http://schema.org/CreativeWork';
88
+ const XSD_INTEGER = 'http://www.w3.org/2001/XMLSchema#integer';
89
+ const XSD_DECIMAL = 'http://www.w3.org/2001/XMLSchema#decimal';
90
+ const XSD_BOOLEAN = 'http://www.w3.org/2001/XMLSchema#boolean';
91
+ const ACL = 'http://www.w3.org/ns/auth/acl#';
92
+ const ACP = 'http://www.w3.org/ns/solid/acp#';
93
+ const AS = 'https://www.w3.org/ns/activitystreams#';
94
+ const ODRL = 'http://www.w3.org/ns/odrl/2/';
95
+ const RDF_MODELS_SYNTHETIC_THREAD_COUNT = 64;
44
96
  const PERFORMANCE_P95_MIN_ABSOLUTE_HEADROOM_MS = 25;
45
97
  const PERFORMANCE_P95_MAX_RATIO = 8;
98
+ const POSTGRES_CONCURRENCY_GATE_QUERY_CASE_NAMES = [
99
+ 'modeled thread message page query',
100
+ 'scheduled task trigger keyset continuation query',
101
+ 'settings owner category keyset query',
102
+ 'provider model credential ordered join query',
103
+ ];
46
104
  exports.rdfModelsBenchmarkCases = [
47
105
  {
48
106
  name: 'list chats',
@@ -89,6 +147,21 @@ exports.rdfModelsBenchmarkCases = [
89
147
  },
90
148
  expectedPlan: ['graph-scope', 'type-filter', 'limit'],
91
149
  },
150
+ {
151
+ name: 'threads by modeled chat relation',
152
+ resource: 'thread',
153
+ purpose: 'thread.chat relation follows the models SIOC has_parent predicate, not a product-local chatId field',
154
+ minScale: 'small',
155
+ query: {
156
+ pattern: {
157
+ predicate: namedNode(SIOC_HAS_PARENT),
158
+ object: namedNode('https://pod.example/alice/.data/chat/default/index.ttl#this'),
159
+ graph: namedNode('https://pod.example/alice/.data/chat/default/index.ttl'),
160
+ },
161
+ options: { order: ['subject'], limit: 100 },
162
+ },
163
+ expectedPlan: ['graph-scope', 'predicate-object-filter', 'limit'],
164
+ },
92
165
  {
93
166
  name: 'list threads by task',
94
167
  resource: 'thread',
@@ -104,6 +177,35 @@ exports.rdfModelsBenchmarkCases = [
104
177
  },
105
178
  expectedPlan: ['graph-scope', 'type-filter', 'limit'],
106
179
  },
180
+ {
181
+ name: 'messages by modeled thread relation',
182
+ resource: 'message',
183
+ purpose: 'message.thread relation follows the models SIOC has_container predicate',
184
+ minScale: 'small',
185
+ query: {
186
+ pattern: {
187
+ predicate: namedNode(SIOC_HAS_CONTAINER),
188
+ object: namedNode('https://pod.example/alice/.data/chat/default/index.ttl#thread_1'),
189
+ graph: { $startsWith: 'https://pod.example/alice/.data/chat/default/2026/05/' },
190
+ },
191
+ options: { order: ['subject'], limit: 100 },
192
+ },
193
+ expectedPlan: ['graph-scope', 'predicate-object-filter', 'limit'],
194
+ },
195
+ {
196
+ name: 'chat latest message pointer',
197
+ resource: 'chat',
198
+ purpose: 'chat list hydration can resolve the latest-message URI stored on the Chat resource',
199
+ minScale: 'small',
200
+ query: {
201
+ pattern: {
202
+ predicate: namedNode(`${UDFS}lastMessage`),
203
+ graph: namedNode('https://pod.example/alice/.data/chat/default/index.ttl'),
204
+ },
205
+ options: { order: ['subject'], limit: 20 },
206
+ },
207
+ expectedPlan: ['graph-scope', 'predicate-filter', 'limit'],
208
+ },
107
209
  {
108
210
  name: 'list messages by thread',
109
211
  resource: 'message',
@@ -235,6 +337,51 @@ exports.rdfModelsBenchmarkCases = [
235
337
  },
236
338
  expectedPlan: ['graph-scope', 'predicate-object-range-filter', 'order', 'limit'],
237
339
  },
340
+ {
341
+ name: 'cron tasks due time',
342
+ resource: 'task',
343
+ purpose: 'task scheduler can poll active cron/interval tasks directly from the Task model fields',
344
+ minScale: 'small',
345
+ query: {
346
+ pattern: {
347
+ predicate: namedNode(`${UDFS}nextRunAt`),
348
+ object: { $lte: literal('2026-05-18T01:30:00.000Z') },
349
+ graph: { $startsWith: 'https://pod.example/alice/.data/task/' },
350
+ },
351
+ options: { order: ['object'], limit: 100 },
352
+ },
353
+ expectedPlan: ['graph-scope', 'predicate-object-range-filter', 'order', 'limit'],
354
+ },
355
+ {
356
+ name: 'waiting input runs',
357
+ resource: 'run',
358
+ purpose: 'runtime steering can find runs parked for approval or client tool output',
359
+ minScale: 'small',
360
+ query: {
361
+ pattern: {
362
+ predicate: namedNode(`${UDFS}status`),
363
+ object: literal('waiting_input'),
364
+ graph: { $startsWith: 'https://pod.example/alice/.data/task/' },
365
+ },
366
+ options: { order: ['subject'], limit: 100 },
367
+ },
368
+ expectedPlan: ['graph-scope', 'predicate-object-filter', 'limit'],
369
+ },
370
+ {
371
+ name: 'runs by lease owner',
372
+ resource: 'run',
373
+ purpose: 'distributed workers can look up currently leased runs without scanning all runtime facts',
374
+ minScale: 'small',
375
+ query: {
376
+ pattern: {
377
+ predicate: namedNode(`${UDFS}leaseOwner`),
378
+ object: literal('worker-1'),
379
+ graph: { $startsWith: 'https://pod.example/alice/.data/task/default/' },
380
+ },
381
+ options: { order: ['subject'], limit: 100 },
382
+ },
383
+ expectedPlan: ['graph-scope', 'predicate-object-filter', 'limit'],
384
+ },
238
385
  {
239
386
  name: 'search message literals',
240
387
  resource: 'message',
@@ -276,6 +423,111 @@ exports.rdfModelsBenchmarkCases = [
276
423
  },
277
424
  expectedPlan: ['graph-scope', 'predicate-filter', 'limit'],
278
425
  },
426
+ {
427
+ name: 'load webid profile',
428
+ resource: 'profile',
429
+ purpose: 'WebID profile lookup must stay graph-scoped for profile/card reads',
430
+ minScale: 'medium',
431
+ query: {
432
+ pattern: {
433
+ subject: namedNode('https://pod.example/alice/profile/card#me'),
434
+ predicate: namedNode(RDF_TYPE),
435
+ object: namedNode(FOAF_PERSON),
436
+ graph: namedNode('https://pod.example/alice/profile/card'),
437
+ },
438
+ },
439
+ expectedPlan: ['graph-scope', 'type-filter'],
440
+ },
441
+ {
442
+ name: 'profile public read acl',
443
+ resource: 'acl',
444
+ purpose: 'WebACL profile/card public read authorization lookup stays on graph + predicate/object filters',
445
+ minScale: 'medium',
446
+ query: {
447
+ pattern: {
448
+ predicate: namedNode(`${ACL}mode`),
449
+ object: namedNode(`${ACL}Read`),
450
+ graph: namedNode('https://pod.example/alice/profile/card.acl'),
451
+ },
452
+ options: { order: ['subject'], limit: 20 },
453
+ },
454
+ expectedPlan: ['graph-scope', 'predicate-object-filter', 'limit'],
455
+ },
456
+ {
457
+ name: 'profile public read acr',
458
+ resource: 'acr',
459
+ purpose: 'ACP profile access-control relation lookup stays graph-scoped when cloud defaults to ACR',
460
+ minScale: 'medium',
461
+ query: {
462
+ pattern: {
463
+ subject: namedNode('https://pod.example/alice/profile/card'),
464
+ predicate: namedNode(`${ACP}accessControl`),
465
+ graph: namedNode('https://pod.example/alice/profile/.acr'),
466
+ },
467
+ options: { order: ['object'], limit: 20 },
468
+ },
469
+ expectedPlan: ['graph-scope', 'predicate-filter', 'limit'],
470
+ },
471
+ {
472
+ name: 'list issues',
473
+ resource: 'issue',
474
+ purpose: 'shared issue resource list under the models issue base',
475
+ minScale: 'medium',
476
+ query: {
477
+ pattern: {
478
+ predicate: namedNode(RDF_TYPE),
479
+ object: namedNode(`${UDFS}Issue`),
480
+ graph: { $startsWith: 'https://pod.example/alice/.data/issues/' },
481
+ },
482
+ options: { order: ['subject'], limit: 50 },
483
+ },
484
+ expectedPlan: ['graph-scope', 'type-filter', 'limit'],
485
+ },
486
+ {
487
+ name: 'pending approvals',
488
+ resource: 'approval',
489
+ purpose: 'approval request queue lookup by status under date-bucketed approval documents',
490
+ minScale: 'medium',
491
+ query: {
492
+ pattern: {
493
+ predicate: namedNode(`${UDFS}status`),
494
+ object: literal('pending'),
495
+ graph: { $startsWith: 'https://pod.example/alice/.data/approvals/' },
496
+ },
497
+ options: { order: ['subject'], limit: 50 },
498
+ },
499
+ expectedPlan: ['graph-scope', 'predicate-object-filter', 'limit'],
500
+ },
501
+ {
502
+ name: 'active autonomy grants',
503
+ resource: 'grant',
504
+ purpose: 'autonomy grant policy lookup by ODRL action under settings/autonomy',
505
+ minScale: 'medium',
506
+ query: {
507
+ pattern: {
508
+ predicate: namedNode(`${ODRL}action`),
509
+ object: namedNode(`${UDFS}runTool`),
510
+ graph: { $startsWith: 'https://pod.example/alice/settings/autonomy/grants/' },
511
+ },
512
+ options: { order: ['subject'], limit: 50 },
513
+ },
514
+ expectedPlan: ['graph-scope', 'predicate-object-filter', 'limit'],
515
+ },
516
+ {
517
+ name: 'list inbox notifications',
518
+ resource: 'inboxNotification',
519
+ purpose: 'Solid inbox activity list uses graph-scoped type lookup rather than a pod-wide scan',
520
+ minScale: 'medium',
521
+ query: {
522
+ pattern: {
523
+ predicate: namedNode(RDF_TYPE),
524
+ object: namedNode(`${AS}Activity`),
525
+ graph: { $startsWith: 'https://pod.example/alice/inbox/' },
526
+ },
527
+ options: { order: ['subject'], limit: 50 },
528
+ },
529
+ expectedPlan: ['graph-scope', 'type-filter', 'limit'],
530
+ },
279
531
  {
280
532
  name: 'list providers',
281
533
  resource: 'aiProvider',
@@ -284,7 +536,7 @@ exports.rdfModelsBenchmarkCases = [
284
536
  query: {
285
537
  pattern: {
286
538
  predicate: namedNode(RDF_TYPE),
287
- object: namedNode(`${UDFS}Provider`),
539
+ object: namedNode(`${XPOD_AI}Provider`),
288
540
  graph: { $startsWith: 'https://pod.example/alice/settings/providers/' },
289
541
  },
290
542
  },
@@ -297,7 +549,7 @@ exports.rdfModelsBenchmarkCases = [
297
549
  minScale: 'small',
298
550
  query: {
299
551
  pattern: {
300
- predicate: namedNode(`${UDFS}isProvidedBy`),
552
+ predicate: namedNode(`${XPOD_AI}isProvidedBy`),
301
553
  object: namedNode('https://pod.example/alice/settings/providers/anthropic.ttl'),
302
554
  },
303
555
  },
@@ -310,7 +562,7 @@ exports.rdfModelsBenchmarkCases = [
310
562
  minScale: 'small',
311
563
  query: {
312
564
  pattern: {
313
- predicate: namedNode(`${UDFS}provider`),
565
+ predicate: namedNode(`${XPOD_CREDENTIAL}provider`),
314
566
  object: namedNode('https://pod.example/alice/settings/providers/anthropic.ttl'),
315
567
  },
316
568
  },
@@ -361,6 +613,186 @@ exports.rdfModelsBenchmarkCases = [
361
613
  },
362
614
  expectedPlan: ['graph-scope', 'type-filter', 'limit'],
363
615
  },
616
+ {
617
+ name: 'list sessions',
618
+ resource: 'session',
619
+ purpose: 'runtime session list under the shared models session resource base',
620
+ minScale: 'small',
621
+ query: {
622
+ pattern: {
623
+ predicate: namedNode(RDF_TYPE),
624
+ object: namedNode(`${UDFS}Session`),
625
+ graph: { $startsWith: 'https://pod.example/alice/.data/sessions/' },
626
+ },
627
+ options: { order: ['subject'], limit: 50 },
628
+ },
629
+ expectedPlan: ['graph-scope', 'type-filter', 'limit'],
630
+ },
631
+ {
632
+ name: 'active sessions',
633
+ resource: 'session',
634
+ purpose: 'session manager active-session lookup by lifecycle status',
635
+ minScale: 'small',
636
+ query: {
637
+ pattern: {
638
+ predicate: namedNode(`${UDFS}sessionStatus`),
639
+ object: literal('active'),
640
+ graph: { $startsWith: 'https://pod.example/alice/.data/sessions/' },
641
+ },
642
+ options: { order: ['subject'], limit: 50 },
643
+ },
644
+ expectedPlan: ['graph-scope', 'predicate-object-filter', 'limit'],
645
+ },
646
+ {
647
+ name: 'audit entries by actor',
648
+ resource: 'audit',
649
+ purpose: 'audit trail lookup by WebID actor under date-bucketed audit documents',
650
+ minScale: 'medium',
651
+ query: {
652
+ pattern: {
653
+ predicate: namedNode(`${UDFS}actor`),
654
+ object: namedNode('https://pod.example/alice/profile/card#me'),
655
+ graph: { $startsWith: 'https://pod.example/alice/.data/audits/' },
656
+ },
657
+ options: { order: ['subject'], limit: 50 },
658
+ },
659
+ expectedPlan: ['graph-scope', 'predicate-object-filter', 'limit'],
660
+ },
661
+ {
662
+ name: 'list ai configs',
663
+ resource: 'aiConfig',
664
+ purpose: 'AI runtime singleton settings lookup under /settings/ai/config.ttl',
665
+ minScale: 'small',
666
+ query: {
667
+ pattern: {
668
+ predicate: namedNode(RDF_TYPE),
669
+ object: namedNode(`${XPOD_AI}AIConfig`),
670
+ graph: namedNode('https://pod.example/alice/settings/ai/config.ttl'),
671
+ },
672
+ options: { order: ['subject'], limit: 20 },
673
+ },
674
+ expectedPlan: ['graph-scope', 'type-filter', 'limit'],
675
+ },
676
+ {
677
+ name: 'list settings',
678
+ resource: 'settings',
679
+ purpose: 'settings resource list under /settings uses schema:PropertyValue with graph scoping',
680
+ minScale: 'small',
681
+ query: {
682
+ pattern: {
683
+ predicate: namedNode(RDF_TYPE),
684
+ object: namedNode(SCHEMA_PROPERTY_VALUE),
685
+ graph: { $startsWith: 'https://pod.example/alice/settings/' },
686
+ },
687
+ options: { order: ['subject'], limit: 50 },
688
+ },
689
+ expectedPlan: ['graph-scope', 'type-filter', 'limit'],
690
+ },
691
+ {
692
+ name: 'sensitive settings',
693
+ resource: 'settings',
694
+ purpose: 'settings sensitivity flag uses the shared model predicate and stays exact-literal scoped',
695
+ minScale: 'small',
696
+ query: {
697
+ pattern: {
698
+ predicate: namedNode(`${UDFS}status`),
699
+ object: literal('true', namedNode(XSD_BOOLEAN)),
700
+ graph: { $startsWith: 'https://pod.example/alice/settings/' },
701
+ },
702
+ options: { order: ['subject'], limit: 50 },
703
+ },
704
+ expectedPlan: ['graph-scope', 'predicate-object-filter', 'limit'],
705
+ },
706
+ {
707
+ name: 'active vector stores',
708
+ resource: 'vectorStore',
709
+ purpose: 'vector store registry lookup by active status',
710
+ minScale: 'small',
711
+ query: {
712
+ pattern: {
713
+ predicate: namedNode(`${XPOD_AI}status`),
714
+ object: literal('active'),
715
+ graph: namedNode('https://pod.example/alice/settings/ai/vector-stores.ttl'),
716
+ },
717
+ options: { order: ['subject'], limit: 50 },
718
+ },
719
+ expectedPlan: ['graph-scope', 'predicate-object-filter', 'limit'],
720
+ },
721
+ {
722
+ name: 'indexed files by status',
723
+ resource: 'indexedFile',
724
+ purpose: 'indexed-file registry lookup by indexing status',
725
+ minScale: 'small',
726
+ query: {
727
+ pattern: {
728
+ predicate: namedNode(`${XPOD_AI}status`),
729
+ object: literal('indexed'),
730
+ graph: namedNode('https://pod.example/alice/settings/ai/indexed-files.ttl'),
731
+ },
732
+ options: { order: ['subject'], limit: 50 },
733
+ },
734
+ expectedPlan: ['graph-scope', 'predicate-object-filter', 'limit'],
735
+ },
736
+ {
737
+ name: 'running agent statuses',
738
+ resource: 'agentStatus',
739
+ purpose: 'agent runtime status lookup by running state',
740
+ minScale: 'small',
741
+ query: {
742
+ pattern: {
743
+ predicate: namedNode(`${XPOD_AI}status`),
744
+ object: literal('running'),
745
+ graph: namedNode('https://pod.example/alice/settings/ai/agent-status.ttl'),
746
+ },
747
+ options: { order: ['subject'], limit: 50 },
748
+ },
749
+ expectedPlan: ['graph-scope', 'predicate-object-filter', 'limit'],
750
+ },
751
+ {
752
+ name: 'oauth credentials expiring',
753
+ resource: 'credential',
754
+ purpose: 'OAuth credential rotation can find active tokens nearing expiry from the shared credential model',
755
+ minScale: 'small',
756
+ query: {
757
+ pattern: {
758
+ predicate: namedNode(`${XPOD_CREDENTIAL}oauthExpiresAt`),
759
+ object: { $lte: literal('2026-05-19T00:00:00.000Z') },
760
+ graph: namedNode('https://pod.example/alice/settings/credentials.ttl'),
761
+ },
762
+ options: { order: ['object'], limit: 50 },
763
+ },
764
+ expectedPlan: ['graph-scope', 'predicate-object-range-filter', 'order', 'limit'],
765
+ },
766
+ {
767
+ name: 'reply messages',
768
+ resource: 'message',
769
+ purpose: 'message reply chains use the semantic replyTo relation rather than local message ids',
770
+ minScale: 'small',
771
+ query: {
772
+ pattern: {
773
+ predicate: namedNode(`${UDFS}replyTo`),
774
+ object: namedNode('https://pod.example/alice/.data/chat/default/2026/05/18/messages.ttl#msg_1'),
775
+ graph: { $startsWith: 'https://pod.example/alice/.data/chat/default/2026/05/' },
776
+ },
777
+ options: { order: ['subject'], limit: 50 },
778
+ },
779
+ expectedPlan: ['graph-scope', 'predicate-object-filter', 'limit'],
780
+ },
781
+ {
782
+ name: 'routed messages by target agent',
783
+ resource: 'message',
784
+ purpose: 'multi-agent routing can locate messages assigned to an agent without scanning message content',
785
+ minScale: 'small',
786
+ query: {
787
+ pattern: {
788
+ predicate: namedNode(`${UDFS}routeTargetAgentId`),
789
+ object: literal('secretary'),
790
+ graph: { $startsWith: 'https://pod.example/alice/.data/chat/default/2026/05/' },
791
+ },
792
+ options: { order: ['subject'], limit: 50 },
793
+ },
794
+ expectedPlan: ['graph-scope', 'predicate-object-filter', 'limit'],
795
+ },
364
796
  ];
365
797
  exports.rdfModelsQueryBenchmarkCases = [
366
798
  {
@@ -395,175 +827,2573 @@ exports.rdfModelsQueryBenchmarkCases = [
395
827
  expectedPlan: ['join-index', 'join-order-pushdown', 'join-limit-pushdown'],
396
828
  },
397
829
  {
398
- name: 'next queued run by workspace query',
399
- resource: 'run',
400
- purpose: 'run state center scheduler query keeps status/workspace/date joins in SQL before LIMIT',
830
+ name: 'thread message keyset page query',
831
+ resource: 'message',
832
+ purpose: 'date-bucketed message timeline keeps keyset cursor range, ordering, and pagination inside SQL self-join',
401
833
  minScale: 'small',
834
+ minReturnedRows: 2,
402
835
  query: {
403
836
  patterns: [
404
837
  {
405
- graph: { $startsWith: 'https://pod.example/alice/.data/task/default/' },
406
- subject: { variable: 'run' },
838
+ graph: { $startsWith: 'https://pod.example/alice/.data/chat/default/' },
839
+ subject: { variable: 'message' },
840
+ predicate: namedNode(SIOC_HAS_MEMBER),
841
+ object: namedNode('https://pod.example/alice/.data/chat/default/index.ttl#thread_1'),
842
+ },
843
+ {
844
+ graph: { $startsWith: 'https://pod.example/alice/.data/chat/default/' },
845
+ subject: { variable: 'message' },
846
+ predicate: namedNode(DCT_CREATED),
847
+ object: { variable: 'createdAt' },
848
+ },
849
+ ],
850
+ filters: [
851
+ {
852
+ variable: 'createdAt',
853
+ operator: '$lt',
854
+ value: literal('2026-05-18T01:04:03.000Z'),
855
+ },
856
+ ],
857
+ select: ['message', 'createdAt'],
858
+ orderBy: [
859
+ {
860
+ variable: 'createdAt',
861
+ direction: 'desc',
862
+ },
863
+ ],
864
+ limit: 2,
865
+ },
866
+ expectedPlan: ['join-index', 'range-filter-pushdown', 'join-order-pushdown', 'join-limit-pushdown'],
867
+ },
868
+ {
869
+ name: 'thread context window query',
870
+ resource: 'message',
871
+ purpose: 'agent context assembly keeps message type/thread/created/score star join and pagination inside SQL',
872
+ minScale: 'small',
873
+ minReturnedRows: 2,
874
+ query: {
875
+ patterns: [
876
+ {
877
+ graph: { $startsWith: 'https://pod.example/alice/.data/chat/default/' },
878
+ subject: { variable: 'message' },
879
+ predicate: namedNode(RDF_TYPE),
880
+ object: namedNode(`${MEETING}Message`),
881
+ },
882
+ {
883
+ graph: { $startsWith: 'https://pod.example/alice/.data/chat/default/' },
884
+ subject: { variable: 'message' },
885
+ predicate: namedNode(SIOC_HAS_MEMBER),
886
+ object: namedNode('https://pod.example/alice/.data/chat/default/index.ttl#thread_1'),
887
+ },
888
+ {
889
+ graph: { $startsWith: 'https://pod.example/alice/.data/chat/default/' },
890
+ subject: { variable: 'message' },
891
+ predicate: namedNode(DCT_CREATED),
892
+ object: { variable: 'createdAt' },
893
+ },
894
+ {
895
+ graph: { $startsWith: 'https://pod.example/alice/.data/chat/default/' },
896
+ subject: { variable: 'message' },
897
+ predicate: namedNode(`${UDFS}score`),
898
+ object: { variable: 'score' },
899
+ },
900
+ ],
901
+ filters: [
902
+ {
903
+ variable: 'score',
904
+ operator: '$termType',
905
+ value: 'numeric',
906
+ },
907
+ ],
908
+ select: ['message', 'createdAt', 'score'],
909
+ orderBy: [
910
+ {
911
+ variable: 'createdAt',
912
+ direction: 'desc',
913
+ },
914
+ ],
915
+ limit: 20,
916
+ },
917
+ expectedPlan: ['join-index', 'join-order-pushdown', 'join-limit-pushdown'],
918
+ },
919
+ {
920
+ name: 'modeled thread message page query',
921
+ resource: 'message',
922
+ purpose: 'message pagination follows the models message.thread SIOC has_container relation',
923
+ minScale: 'small',
924
+ minReturnedRows: 2,
925
+ query: {
926
+ patterns: [
927
+ {
928
+ graph: { $startsWith: 'https://pod.example/alice/.data/chat/default/2026/05/' },
929
+ subject: { variable: 'message' },
930
+ predicate: namedNode(SIOC_HAS_CONTAINER),
931
+ object: namedNode('https://pod.example/alice/.data/chat/default/index.ttl#thread_1'),
932
+ },
933
+ {
934
+ graph: { $startsWith: 'https://pod.example/alice/.data/chat/default/2026/05/' },
935
+ subject: { variable: 'message' },
936
+ predicate: namedNode(DCT_CREATED),
937
+ object: { variable: 'createdAt' },
938
+ },
939
+ {
940
+ graph: { $startsWith: 'https://pod.example/alice/.data/chat/default/2026/05/' },
941
+ subject: { variable: 'message' },
942
+ predicate: namedNode(`${UDFS}messageStatus`),
943
+ object: literal('completed'),
944
+ },
945
+ ],
946
+ select: ['message', 'createdAt'],
947
+ orderBy: [
948
+ {
949
+ variable: 'createdAt',
950
+ direction: 'desc',
951
+ },
952
+ ],
953
+ limit: 20,
954
+ },
955
+ expectedPlan: ['join-index', 'join-order-pushdown', 'join-limit-pushdown'],
956
+ },
957
+ {
958
+ name: 'chat latest message hydration query',
959
+ resource: 'chat',
960
+ purpose: 'chat list hydration joins Chat latest-message pointer to message content and status',
961
+ minScale: 'small',
962
+ minReturnedRows: 1,
963
+ query: {
964
+ patterns: [
965
+ {
966
+ graph: namedNode('https://pod.example/alice/.data/chat/default/index.ttl'),
967
+ subject: { variable: 'chat' },
968
+ predicate: namedNode(RDF_TYPE),
969
+ object: namedNode(`${MEETING}LongChat`),
970
+ },
971
+ {
972
+ graph: namedNode('https://pod.example/alice/.data/chat/default/index.ttl'),
973
+ subject: { variable: 'chat' },
974
+ predicate: namedNode(`${UDFS}lastMessage`),
975
+ object: { variable: 'message' },
976
+ },
977
+ {
978
+ graph: { $startsWith: 'https://pod.example/alice/.data/chat/default/2026/05/' },
979
+ subject: { variable: 'message' },
980
+ predicate: namedNode(SIOC_CONTENT),
981
+ object: { variable: 'content' },
982
+ },
983
+ {
984
+ graph: { $startsWith: 'https://pod.example/alice/.data/chat/default/2026/05/' },
985
+ subject: { variable: 'message' },
986
+ predicate: namedNode(`${UDFS}messageStatus`),
987
+ object: literal('completed'),
988
+ },
989
+ ],
990
+ select: ['chat', 'message', 'content'],
991
+ limit: 10,
992
+ },
993
+ expectedPlan: ['join-index', 'join-limit-pushdown'],
994
+ },
995
+ {
996
+ name: 'thread chat hydration query',
997
+ resource: 'thread',
998
+ purpose: 'thread list joins the models thread.chat SIOC has_parent relation back to Chat metadata',
999
+ minScale: 'small',
1000
+ minReturnedRows: 1,
1001
+ query: {
1002
+ patterns: [
1003
+ {
1004
+ graph: namedNode('https://pod.example/alice/.data/chat/default/index.ttl'),
1005
+ subject: { variable: 'thread' },
1006
+ predicate: namedNode(SIOC_HAS_PARENT),
1007
+ object: { variable: 'chat' },
1008
+ },
1009
+ {
1010
+ graph: namedNode('https://pod.example/alice/.data/chat/default/index.ttl'),
1011
+ subject: { variable: 'thread' },
1012
+ predicate: namedNode(`${UDFS}status`),
1013
+ object: literal('active'),
1014
+ },
1015
+ {
1016
+ graph: namedNode('https://pod.example/alice/.data/chat/default/index.ttl'),
1017
+ subject: { variable: 'chat' },
1018
+ predicate: namedNode(DCT_TITLE),
1019
+ object: { variable: 'title' },
1020
+ },
1021
+ ],
1022
+ select: ['thread', 'chat', 'title'],
1023
+ orderBy: [
1024
+ {
1025
+ variable: 'thread',
1026
+ direction: 'asc',
1027
+ },
1028
+ ],
1029
+ limit: 20,
1030
+ },
1031
+ expectedPlan: ['join-index', 'join-order-pushdown', 'join-limit-pushdown'],
1032
+ },
1033
+ {
1034
+ name: 'next queued run by workspace query',
1035
+ resource: 'run',
1036
+ purpose: 'run state center scheduler query keeps status/workspace/date joins in SQL before LIMIT',
1037
+ minScale: 'small',
1038
+ query: {
1039
+ patterns: [
1040
+ {
1041
+ graph: { $startsWith: 'https://pod.example/alice/.data/task/default/' },
1042
+ subject: { variable: 'run' },
407
1043
  predicate: namedNode(`${UDFS}status`),
408
1044
  object: literal('queued'),
409
1045
  },
410
1046
  {
411
- graph: { $startsWith: 'https://pod.example/alice/.data/task/default/' },
412
- subject: { variable: 'run' },
413
- predicate: namedNode(`${UDFS}workspace`),
414
- object: namedNode('file://macbook.local/Users/alice/project/'),
1047
+ graph: { $startsWith: 'https://pod.example/alice/.data/task/default/' },
1048
+ subject: { variable: 'run' },
1049
+ predicate: namedNode(`${UDFS}workspace`),
1050
+ object: namedNode('file://macbook.local/Users/alice/project/'),
1051
+ },
1052
+ {
1053
+ graph: { $startsWith: 'https://pod.example/alice/.data/task/default/' },
1054
+ subject: { variable: 'run' },
1055
+ predicate: namedNode(DCT_CREATED),
1056
+ object: { variable: 'createdAt' },
1057
+ },
1058
+ ],
1059
+ select: ['run', 'createdAt'],
1060
+ orderBy: [
1061
+ {
1062
+ variable: 'createdAt',
1063
+ direction: 'asc',
1064
+ },
1065
+ ],
1066
+ limit: 1,
1067
+ },
1068
+ expectedPlan: ['join-index', 'join-order-pushdown', 'join-limit-pushdown'],
1069
+ },
1070
+ {
1071
+ name: 'run steps by run query',
1072
+ resource: 'runStep',
1073
+ purpose: 'one-to-many run-step lookup keeps type and run relation in SQL self-join',
1074
+ minScale: 'small',
1075
+ query: {
1076
+ patterns: [
1077
+ {
1078
+ graph: { $startsWith: 'https://pod.example/alice/.data/task/default/2026/05/' },
1079
+ subject: { variable: 'step' },
1080
+ predicate: namedNode(RDF_TYPE),
1081
+ object: namedNode(`${UDFS}RunStep`),
1082
+ },
1083
+ {
1084
+ graph: { $startsWith: 'https://pod.example/alice/.data/task/default/2026/05/' },
1085
+ subject: { variable: 'step' },
1086
+ predicate: namedNode(`${UDFS}run`),
1087
+ object: namedNode('https://pod.example/alice/.data/task/default/2026/05/18/runs.ttl#run_1'),
1088
+ },
1089
+ ],
1090
+ select: ['step'],
1091
+ orderBy: [
1092
+ {
1093
+ variable: 'step',
1094
+ direction: 'asc',
1095
+ },
1096
+ ],
1097
+ limit: 50,
1098
+ },
1099
+ expectedPlan: ['join-index', 'join-order-pushdown', 'join-limit-pushdown'],
1100
+ },
1101
+ {
1102
+ name: 'task run execution detail query',
1103
+ resource: 'run',
1104
+ purpose: 'task detail hydration joins Task, Run, Thread, and RunStep facts without falling back to per-resource scans',
1105
+ minScale: 'small',
1106
+ minReturnedRows: 2,
1107
+ query: {
1108
+ patterns: [
1109
+ {
1110
+ graph: { $startsWith: 'https://pod.example/alice/.data/task/' },
1111
+ subject: { variable: 'task' },
1112
+ predicate: namedNode(RDF_TYPE),
1113
+ object: namedNode(`${UDFS}Task`),
1114
+ },
1115
+ {
1116
+ graph: { $startsWith: 'https://pod.example/alice/.data/task/default/' },
1117
+ subject: { variable: 'run' },
1118
+ predicate: namedNode(RDF_TYPE),
1119
+ object: namedNode(`${UDFS}Run`),
1120
+ },
1121
+ {
1122
+ graph: { $startsWith: 'https://pod.example/alice/.data/task/default/' },
1123
+ subject: { variable: 'run' },
1124
+ predicate: namedNode(`${UDFS}task`),
1125
+ object: { variable: 'task' },
1126
+ },
1127
+ {
1128
+ graph: { $startsWith: 'https://pod.example/alice/.data/task/default/' },
1129
+ subject: { variable: 'run' },
1130
+ predicate: namedNode(`${UDFS}inThread`),
1131
+ object: { variable: 'thread' },
1132
+ },
1133
+ {
1134
+ graph: { $startsWith: 'https://pod.example/alice/.data/task/default/2026/05/' },
1135
+ subject: { variable: 'step' },
1136
+ predicate: namedNode(`${UDFS}run`),
1137
+ object: { variable: 'run' },
1138
+ },
1139
+ {
1140
+ graph: { $startsWith: 'https://pod.example/alice/.data/task/default/2026/05/' },
1141
+ subject: { variable: 'step' },
1142
+ predicate: namedNode(`${UDFS}status`),
1143
+ object: { variable: 'stepType' },
1144
+ },
1145
+ ],
1146
+ select: ['task', 'run', 'thread', 'step', 'stepType'],
1147
+ orderBy: [
1148
+ {
1149
+ variable: 'step',
1150
+ direction: 'asc',
1151
+ },
1152
+ ],
1153
+ limit: 10,
1154
+ },
1155
+ expectedPlan: ['join-index', 'join-order-pushdown', 'join-limit-pushdown'],
1156
+ },
1157
+ {
1158
+ name: 'task materialization active due query',
1159
+ resource: 'schedule',
1160
+ purpose: 'task scheduler materialization keeps active status and due-time filter in SQL self-join',
1161
+ minScale: 'small',
1162
+ query: {
1163
+ patterns: [
1164
+ {
1165
+ graph: { $startsWith: 'https://pod.example/alice/.data/task/default/' },
1166
+ subject: { variable: 'schedule' },
1167
+ predicate: namedNode(RDF_TYPE),
1168
+ object: namedNode(`${UDFS}Schedule`),
1169
+ },
1170
+ {
1171
+ graph: { $startsWith: 'https://pod.example/alice/.data/task/default/' },
1172
+ subject: { variable: 'schedule' },
1173
+ predicate: namedNode(`${UDFS}status`),
1174
+ object: literal('active'),
1175
+ },
1176
+ {
1177
+ graph: { $startsWith: 'https://pod.example/alice/.data/task/default/' },
1178
+ subject: { variable: 'schedule' },
1179
+ predicate: namedNode(`${UDFS}nextRunAt`),
1180
+ object: { variable: 'nextRunAt' },
1181
+ },
1182
+ ],
1183
+ filters: [
1184
+ {
1185
+ variable: 'nextRunAt',
1186
+ operator: '$lte',
1187
+ value: literal('2026-05-18T01:30:00.000Z'),
1188
+ },
1189
+ ],
1190
+ select: ['schedule', 'nextRunAt'],
1191
+ orderBy: [
1192
+ {
1193
+ variable: 'nextRunAt',
1194
+ direction: 'asc',
1195
+ },
1196
+ ],
1197
+ limit: 100,
1198
+ },
1199
+ expectedPlan: ['join-index', 'range-filter-pushdown', 'join-order-pushdown', 'join-limit-pushdown'],
1200
+ },
1201
+ {
1202
+ name: 'scheduled task trigger query',
1203
+ resource: 'task',
1204
+ purpose: 'task scheduler joins trigger kind, active status, workspace, and nextRunAt from Task facts',
1205
+ minScale: 'small',
1206
+ minReturnedRows: 1,
1207
+ query: {
1208
+ patterns: [
1209
+ {
1210
+ graph: { $startsWith: 'https://pod.example/alice/.data/task/' },
1211
+ subject: { variable: 'task' },
1212
+ predicate: namedNode(RDF_TYPE),
1213
+ object: namedNode(`${UDFS}Task`),
1214
+ },
1215
+ {
1216
+ graph: { $startsWith: 'https://pod.example/alice/.data/task/' },
1217
+ subject: { variable: 'task' },
1218
+ predicate: namedNode(`${UDFS}status`),
1219
+ object: literal('active'),
1220
+ },
1221
+ {
1222
+ graph: { $startsWith: 'https://pod.example/alice/.data/task/' },
1223
+ subject: { variable: 'task' },
1224
+ predicate: namedNode(`${UDFS}triggerKind`),
1225
+ object: literal('cron'),
1226
+ },
1227
+ {
1228
+ graph: { $startsWith: 'https://pod.example/alice/.data/task/' },
1229
+ subject: { variable: 'task' },
1230
+ predicate: namedNode(`${UDFS}workspace`),
1231
+ object: namedNode(WORKSPACE),
1232
+ },
1233
+ {
1234
+ graph: { $startsWith: 'https://pod.example/alice/.data/task/' },
1235
+ subject: { variable: 'task' },
1236
+ predicate: namedNode(`${UDFS}nextRunAt`),
1237
+ object: { variable: 'nextRunAt' },
1238
+ },
1239
+ ],
1240
+ filters: [
1241
+ {
1242
+ variable: 'nextRunAt',
1243
+ operator: '$lte',
1244
+ value: literal('2026-05-18T01:30:00.000Z'),
1245
+ },
1246
+ ],
1247
+ select: ['task', 'nextRunAt'],
1248
+ orderBy: [
1249
+ {
1250
+ variable: 'nextRunAt',
1251
+ direction: 'asc',
1252
+ },
1253
+ ],
1254
+ limit: 100,
1255
+ },
1256
+ expectedPlan: ['join-index', 'range-filter-pushdown', 'join-order-pushdown', 'join-limit-pushdown'],
1257
+ },
1258
+ {
1259
+ name: 'scheduled task trigger keyset continuation query',
1260
+ resource: 'task',
1261
+ purpose: 'task scheduler keyset continuation keeps cursor range, ordering, and pagination inside SQL self-join',
1262
+ minScale: 'small',
1263
+ minReturnedRows: 1,
1264
+ query: {
1265
+ patterns: [
1266
+ {
1267
+ graph: { $startsWith: 'https://pod.example/alice/.data/task/' },
1268
+ subject: { variable: 'task' },
1269
+ predicate: namedNode(RDF_TYPE),
1270
+ object: namedNode(`${UDFS}Task`),
1271
+ },
1272
+ {
1273
+ graph: { $startsWith: 'https://pod.example/alice/.data/task/' },
1274
+ subject: { variable: 'task' },
1275
+ predicate: namedNode(`${UDFS}status`),
1276
+ object: literal('active'),
1277
+ },
1278
+ {
1279
+ graph: { $startsWith: 'https://pod.example/alice/.data/task/' },
1280
+ subject: { variable: 'task' },
1281
+ predicate: namedNode(`${UDFS}workspace`),
1282
+ object: namedNode(WORKSPACE),
1283
+ },
1284
+ {
1285
+ graph: { $startsWith: 'https://pod.example/alice/.data/task/' },
1286
+ subject: { variable: 'task' },
1287
+ predicate: namedNode(`${UDFS}nextRunAt`),
1288
+ object: { variable: 'nextRunAt' },
1289
+ },
1290
+ ],
1291
+ filters: [
1292
+ {
1293
+ variable: 'nextRunAt',
1294
+ operator: '$gt',
1295
+ value: literal('2026-05-18T00:30:00.000Z'),
1296
+ },
1297
+ {
1298
+ variable: 'nextRunAt',
1299
+ operator: '$lte',
1300
+ value: literal('2026-05-18T01:30:00.000Z'),
1301
+ },
1302
+ ],
1303
+ select: ['task', 'nextRunAt'],
1304
+ orderBy: [
1305
+ {
1306
+ variable: 'nextRunAt',
1307
+ direction: 'asc',
1308
+ },
1309
+ ],
1310
+ limit: 1,
1311
+ },
1312
+ expectedPlan: ['join-index', 'range-filter-pushdown', 'join-order-pushdown', 'join-limit-pushdown'],
1313
+ },
1314
+ {
1315
+ name: 'leased running run query',
1316
+ resource: 'run',
1317
+ purpose: 'run recovery joins running status with worker lease and heartbeat metadata',
1318
+ minScale: 'small',
1319
+ minReturnedRows: 1,
1320
+ query: {
1321
+ patterns: [
1322
+ {
1323
+ graph: { $startsWith: 'https://pod.example/alice/.data/task/default/' },
1324
+ subject: { variable: 'run' },
1325
+ predicate: namedNode(`${UDFS}status`),
1326
+ object: literal('running'),
1327
+ },
1328
+ {
1329
+ graph: { $startsWith: 'https://pod.example/alice/.data/task/default/' },
1330
+ subject: { variable: 'run' },
1331
+ predicate: namedNode(`${UDFS}leaseOwner`),
1332
+ object: literal('worker-1'),
1333
+ },
1334
+ {
1335
+ graph: { $startsWith: 'https://pod.example/alice/.data/task/default/' },
1336
+ subject: { variable: 'run' },
1337
+ predicate: namedNode(`${UDFS}leaseExpiresAt`),
1338
+ object: { variable: 'leaseExpiresAt' },
1339
+ },
1340
+ {
1341
+ graph: { $startsWith: 'https://pod.example/alice/.data/task/default/' },
1342
+ subject: { variable: 'run' },
1343
+ predicate: namedNode(`${UDFS}heartbeatAt`),
1344
+ object: { variable: 'heartbeatAt' },
1345
+ },
1346
+ ],
1347
+ select: ['run', 'leaseExpiresAt', 'heartbeatAt'],
1348
+ orderBy: [
1349
+ {
1350
+ variable: 'heartbeatAt',
1351
+ direction: 'asc',
1352
+ },
1353
+ ],
1354
+ limit: 20,
1355
+ },
1356
+ expectedPlan: ['join-index', 'join-order-pushdown', 'join-limit-pushdown'],
1357
+ },
1358
+ {
1359
+ name: 'provider model credential join query',
1360
+ resource: 'aiProvider',
1361
+ purpose: 'provider/model/credential relation join can stay on the PostgreSQL RDF-3X join path',
1362
+ minScale: 'small',
1363
+ minReturnedRows: 1,
1364
+ query: {
1365
+ patterns: [
1366
+ {
1367
+ graph: namedNode('https://pod.example/alice/settings/providers/anthropic.ttl'),
1368
+ subject: { variable: 'model' },
1369
+ predicate: namedNode(`${XPOD_AI}isProvidedBy`),
1370
+ object: { variable: 'provider' },
1371
+ },
1372
+ {
1373
+ graph: namedNode('https://pod.example/alice/settings/credentials.ttl'),
1374
+ subject: { variable: 'credential' },
1375
+ predicate: namedNode(`${XPOD_CREDENTIAL}provider`),
1376
+ object: { variable: 'provider' },
1377
+ },
1378
+ ],
1379
+ select: ['model', 'credential'],
1380
+ },
1381
+ expectedPlan: ['join-index'],
1382
+ },
1383
+ {
1384
+ name: 'provider model credential VALUES join query',
1385
+ resource: 'aiProvider',
1386
+ purpose: 'VALUES-constrained provider/model/credential relation join can stay on the RDF-3X values join path',
1387
+ minScale: 'small',
1388
+ minReturnedRows: 1,
1389
+ query: {
1390
+ patterns: [
1391
+ {
1392
+ graph: namedNode('https://pod.example/alice/settings/providers/anthropic.ttl'),
1393
+ subject: { variable: 'model' },
1394
+ predicate: namedNode(`${XPOD_AI}isProvidedBy`),
1395
+ object: { variable: 'provider' },
1396
+ },
1397
+ {
1398
+ graph: namedNode('https://pod.example/alice/settings/credentials.ttl'),
1399
+ subject: { variable: 'credential' },
1400
+ predicate: namedNode(`${XPOD_CREDENTIAL}provider`),
1401
+ object: { variable: 'provider' },
1402
+ },
1403
+ ],
1404
+ values: [
1405
+ {
1406
+ variables: ['provider'],
1407
+ rows: [
1408
+ {
1409
+ provider: namedNode('https://pod.example/alice/settings/providers/anthropic.ttl'),
1410
+ },
1411
+ ],
1412
+ },
1413
+ ],
1414
+ select: ['model', 'credential'],
1415
+ },
1416
+ expectedPlan: ['join-index', 'values-join-pushdown'],
1417
+ },
1418
+ {
1419
+ name: 'provider model credential ordered join query',
1420
+ resource: 'aiProvider',
1421
+ purpose: 'PostgreSQL RDF-3X joins keep hidden ordering variables for paginated settings lists',
1422
+ minScale: 'small',
1423
+ minReturnedRows: 1,
1424
+ query: {
1425
+ patterns: [
1426
+ {
1427
+ graph: namedNode('https://pod.example/alice/settings/providers/anthropic.ttl'),
1428
+ subject: { variable: 'model' },
1429
+ predicate: namedNode(`${XPOD_AI}isProvidedBy`),
1430
+ object: { variable: 'provider' },
1431
+ },
1432
+ {
1433
+ graph: namedNode('https://pod.example/alice/settings/credentials.ttl'),
1434
+ subject: { variable: 'credential' },
1435
+ predicate: namedNode(`${XPOD_CREDENTIAL}provider`),
1436
+ object: { variable: 'provider' },
1437
+ },
1438
+ ],
1439
+ select: ['model', 'credential'],
1440
+ orderBy: [
1441
+ {
1442
+ variable: 'provider',
1443
+ direction: 'asc',
1444
+ },
1445
+ ],
1446
+ limit: 1,
1447
+ },
1448
+ expectedPlan: ['join-index', 'join-order-pushdown', 'join-limit-pushdown'],
1449
+ },
1450
+ {
1451
+ name: 'ai credential selection query',
1452
+ resource: 'credential',
1453
+ purpose: 'shared models credential selection joins active AI credentials with provider default model metadata',
1454
+ minScale: 'small',
1455
+ minReturnedRows: 1,
1456
+ query: {
1457
+ patterns: [
1458
+ {
1459
+ graph: namedNode('https://pod.example/alice/settings/providers/anthropic.ttl'),
1460
+ subject: { variable: 'provider' },
1461
+ predicate: namedNode(RDF_TYPE),
1462
+ object: namedNode(`${XPOD_AI}Provider`),
1463
+ },
1464
+ {
1465
+ graph: namedNode('https://pod.example/alice/settings/providers/anthropic.ttl'),
1466
+ subject: { variable: 'provider' },
1467
+ predicate: namedNode(`${XPOD_AI}defaultModel`),
1468
+ object: { variable: 'model' },
1469
+ },
1470
+ {
1471
+ graph: namedNode('https://pod.example/alice/settings/providers/anthropic.ttl'),
1472
+ subject: { variable: 'model' },
1473
+ predicate: namedNode(`${XPOD_AI}isProvidedBy`),
1474
+ object: { variable: 'provider' },
1475
+ },
1476
+ {
1477
+ graph: namedNode('https://pod.example/alice/settings/providers/anthropic.ttl'),
1478
+ subject: { variable: 'model' },
1479
+ predicate: namedNode(`${XPOD_AI}status`),
1480
+ object: literal('active'),
1481
+ },
1482
+ {
1483
+ graph: namedNode('https://pod.example/alice/settings/credentials.ttl'),
1484
+ subject: { variable: 'credential' },
1485
+ predicate: namedNode(`${XPOD_CREDENTIAL}provider`),
1486
+ object: { variable: 'provider' },
1487
+ },
1488
+ {
1489
+ graph: namedNode('https://pod.example/alice/settings/credentials.ttl'),
1490
+ subject: { variable: 'credential' },
1491
+ predicate: namedNode(`${XPOD_CREDENTIAL}service`),
1492
+ object: literal('ai'),
1493
+ },
1494
+ {
1495
+ graph: namedNode('https://pod.example/alice/settings/credentials.ttl'),
1496
+ subject: { variable: 'credential' },
1497
+ predicate: namedNode(`${XPOD_CREDENTIAL}status`),
1498
+ object: literal('active'),
1499
+ },
1500
+ {
1501
+ graph: namedNode('https://pod.example/alice/settings/credentials.ttl'),
1502
+ subject: { variable: 'credential' },
1503
+ predicate: namedNode(`${XPOD_CREDENTIAL}isDefault`),
1504
+ object: literal('true', namedNode(XSD_BOOLEAN)),
1505
+ },
1506
+ {
1507
+ graph: namedNode('https://pod.example/alice/settings/credentials.ttl'),
1508
+ subject: { variable: 'credential' },
1509
+ predicate: namedNode(`${XPOD_CREDENTIAL}apiKey`),
1510
+ object: { variable: 'apiKey' },
1511
+ },
1512
+ {
1513
+ graph: namedNode('https://pod.example/alice/settings/credentials.ttl'),
1514
+ subject: { variable: 'credential' },
1515
+ predicate: namedNode(`${XPOD_CREDENTIAL}failCount`),
1516
+ object: { variable: 'failCount' },
1517
+ },
1518
+ ],
1519
+ select: ['provider', 'model', 'credential', 'apiKey', 'failCount'],
1520
+ orderBy: [
1521
+ {
1522
+ variable: 'failCount',
1523
+ direction: 'asc',
1524
+ },
1525
+ ],
1526
+ limit: 1,
1527
+ },
1528
+ expectedPlan: ['join-index', 'join-order-pushdown', 'join-limit-pushdown'],
1529
+ },
1530
+ {
1531
+ name: 'provider model credential count query',
1532
+ resource: 'aiProvider',
1533
+ purpose: 'count aggregate can stay inside the PostgreSQL RDF-3X count path',
1534
+ minScale: 'small',
1535
+ minReturnedRows: 1,
1536
+ query: {
1537
+ patterns: [
1538
+ {
1539
+ graph: namedNode('https://pod.example/alice/settings/providers/anthropic.ttl'),
1540
+ subject: { variable: 'model' },
1541
+ predicate: namedNode(`${XPOD_AI}isProvidedBy`),
1542
+ object: { variable: 'provider' },
1543
+ },
1544
+ {
1545
+ graph: namedNode('https://pod.example/alice/settings/credentials.ttl'),
1546
+ subject: { variable: 'credential' },
1547
+ predicate: namedNode(`${XPOD_CREDENTIAL}provider`),
1548
+ object: { variable: 'provider' },
1549
+ },
1550
+ ],
1551
+ aggregates: [
1552
+ {
1553
+ type: 'count',
1554
+ as: 'credentialCount',
1555
+ variable: 'credential',
1556
+ },
1557
+ {
1558
+ type: 'count',
1559
+ as: 'providerCount',
1560
+ variable: 'provider',
1561
+ distinct: true,
1562
+ },
1563
+ ],
1564
+ select: ['credentialCount', 'providerCount'],
1565
+ },
1566
+ expectedPlan: ['join-count-index'],
1567
+ },
1568
+ {
1569
+ name: 'provider credential grouped count query',
1570
+ resource: 'aiProvider',
1571
+ purpose: 'grouped count aggregate can stay inside the PostgreSQL RDF-3X group count path',
1572
+ minScale: 'small',
1573
+ minReturnedRows: 1,
1574
+ query: {
1575
+ patterns: [
1576
+ {
1577
+ graph: namedNode('https://pod.example/alice/settings/providers/anthropic.ttl'),
1578
+ subject: { variable: 'model' },
1579
+ predicate: namedNode(`${XPOD_AI}isProvidedBy`),
1580
+ object: { variable: 'provider' },
1581
+ },
1582
+ {
1583
+ graph: namedNode('https://pod.example/alice/settings/credentials.ttl'),
1584
+ subject: { variable: 'credential' },
1585
+ predicate: namedNode(`${XPOD_CREDENTIAL}provider`),
1586
+ object: { variable: 'provider' },
1587
+ },
1588
+ ],
1589
+ groupBy: ['provider'],
1590
+ aggregates: [
1591
+ {
1592
+ type: 'count',
1593
+ as: 'credentialCount',
1594
+ variable: 'credential',
1595
+ },
1596
+ ],
1597
+ having: [
1598
+ {
1599
+ variable: 'credentialCount',
1600
+ operator: '$gt',
1601
+ value: literal('0', namedNode('http://www.w3.org/2001/XMLSchema#integer')),
1602
+ },
1603
+ ],
1604
+ select: ['provider', 'credentialCount'],
1605
+ orderBy: [
1606
+ {
1607
+ variable: 'credentialCount',
1608
+ direction: 'desc',
1609
+ },
1610
+ ],
1611
+ limit: 1,
1612
+ },
1613
+ expectedPlan: ['group-count-index', 'having-pushdown', 'order', 'limit'],
1614
+ },
1615
+ {
1616
+ name: 'provider credential single-pattern grouped count query',
1617
+ resource: 'credential',
1618
+ purpose: 'single-pattern exact graph grouped count aggregate can stay inside the PostgreSQL RDF-3X group count path',
1619
+ minScale: 'small',
1620
+ minReturnedRows: 1,
1621
+ query: {
1622
+ patterns: [
1623
+ {
1624
+ graph: namedNode('https://pod.example/alice/settings/credentials.ttl'),
1625
+ subject: { variable: 'credential' },
1626
+ predicate: namedNode(`${XPOD_CREDENTIAL}provider`),
1627
+ object: { variable: 'provider' },
1628
+ },
1629
+ ],
1630
+ groupBy: ['provider'],
1631
+ aggregates: [
1632
+ {
1633
+ type: 'count',
1634
+ as: 'credentialCount',
1635
+ variable: 'credential',
1636
+ },
1637
+ ],
1638
+ having: [
1639
+ {
1640
+ variable: 'credentialCount',
1641
+ operator: '$gt',
1642
+ value: literal('0', namedNode('http://www.w3.org/2001/XMLSchema#integer')),
1643
+ },
1644
+ ],
1645
+ select: ['provider', 'credentialCount'],
1646
+ orderBy: [
1647
+ {
1648
+ variable: 'credentialCount',
1649
+ direction: 'desc',
1650
+ },
1651
+ ],
1652
+ limit: 1,
1653
+ },
1654
+ expectedPlan: ['group-count-index', 'having-pushdown', 'order', 'limit'],
1655
+ },
1656
+ {
1657
+ name: 'provider credential fail count aggregate query',
1658
+ resource: 'aiProvider',
1659
+ purpose: 'small grouped numeric aggregate over credential failCount can cut over from RDF-3X to facts by cost',
1660
+ minScale: 'small',
1661
+ minReturnedRows: 1,
1662
+ query: {
1663
+ patterns: [
1664
+ {
1665
+ graph: namedNode('https://pod.example/alice/settings/providers/anthropic.ttl'),
1666
+ subject: { variable: 'model' },
1667
+ predicate: namedNode(`${XPOD_AI}isProvidedBy`),
1668
+ object: { variable: 'provider' },
1669
+ },
1670
+ {
1671
+ graph: namedNode('https://pod.example/alice/settings/credentials.ttl'),
1672
+ subject: { variable: 'credential' },
1673
+ predicate: namedNode(`${XPOD_CREDENTIAL}provider`),
1674
+ object: { variable: 'provider' },
1675
+ },
1676
+ {
1677
+ graph: namedNode('https://pod.example/alice/settings/credentials.ttl'),
1678
+ subject: { variable: 'credential' },
1679
+ predicate: namedNode(`${XPOD_CREDENTIAL}failCount`),
1680
+ object: { variable: 'failCount' },
1681
+ },
1682
+ ],
1683
+ groupBy: ['provider'],
1684
+ aggregates: [
1685
+ {
1686
+ type: 'count',
1687
+ as: 'credentialCount',
1688
+ variable: 'credential',
1689
+ },
1690
+ {
1691
+ type: 'sum',
1692
+ as: 'failCountTotal',
1693
+ variable: 'failCount',
1694
+ },
1695
+ ],
1696
+ select: ['provider', 'credentialCount', 'failCountTotal'],
1697
+ },
1698
+ expectedPlan: ['numeric-aggregate'],
1699
+ },
1700
+ {
1701
+ name: 'oauth credential expiry query',
1702
+ resource: 'credential',
1703
+ purpose: 'credential refresh jobs join service/status/token expiry fields without scanning non-OAuth credentials',
1704
+ minScale: 'small',
1705
+ minReturnedRows: 1,
1706
+ query: {
1707
+ patterns: [
1708
+ {
1709
+ graph: namedNode('https://pod.example/alice/settings/credentials.ttl'),
1710
+ subject: { variable: 'credential' },
1711
+ predicate: namedNode(`${XPOD_CREDENTIAL}service`),
1712
+ object: literal('github'),
1713
+ },
1714
+ {
1715
+ graph: namedNode('https://pod.example/alice/settings/credentials.ttl'),
1716
+ subject: { variable: 'credential' },
1717
+ predicate: namedNode(`${XPOD_CREDENTIAL}status`),
1718
+ object: literal('active'),
1719
+ },
1720
+ {
1721
+ graph: namedNode('https://pod.example/alice/settings/credentials.ttl'),
1722
+ subject: { variable: 'credential' },
1723
+ predicate: namedNode(`${XPOD_CREDENTIAL}oauthExpiresAt`),
1724
+ object: { variable: 'expiresAt' },
1725
+ },
1726
+ ],
1727
+ filters: [
1728
+ {
1729
+ variable: 'expiresAt',
1730
+ operator: '$lte',
1731
+ value: literal('2026-05-19T00:00:00.000Z'),
1732
+ },
1733
+ ],
1734
+ select: ['credential', 'expiresAt'],
1735
+ orderBy: [
1736
+ {
1737
+ variable: 'expiresAt',
1738
+ direction: 'asc',
1739
+ },
1740
+ ],
1741
+ limit: 20,
1742
+ },
1743
+ expectedPlan: ['join-index', 'range-filter-pushdown', 'join-order-pushdown', 'join-limit-pushdown'],
1744
+ },
1745
+ {
1746
+ name: 'profile acl authorization join query',
1747
+ resource: 'acl',
1748
+ purpose: 'WebACL authorization lookup joins access target and mode inside the ACL graph',
1749
+ minScale: 'medium',
1750
+ minReturnedRows: 1,
1751
+ query: {
1752
+ patterns: [
1753
+ {
1754
+ graph: namedNode('https://pod.example/alice/profile/card.acl'),
1755
+ subject: { variable: 'authorization' },
1756
+ predicate: namedNode(`${ACL}accessTo`),
1757
+ object: namedNode('https://pod.example/alice/profile/card'),
1758
+ },
1759
+ {
1760
+ graph: namedNode('https://pod.example/alice/profile/card.acl'),
1761
+ subject: { variable: 'authorization' },
1762
+ predicate: namedNode(`${ACL}mode`),
1763
+ object: namedNode(`${ACL}Read`),
1764
+ },
1765
+ ],
1766
+ select: ['authorization'],
1767
+ limit: 20,
1768
+ },
1769
+ expectedPlan: ['join-index', 'join-limit-pushdown'],
1770
+ },
1771
+ {
1772
+ name: 'profile acr authorization join query',
1773
+ resource: 'acr',
1774
+ purpose: 'ACP access-control lookup joins resource, control node, target, and mode inside the ACR graph',
1775
+ minScale: 'medium',
1776
+ minReturnedRows: 1,
1777
+ query: {
1778
+ patterns: [
1779
+ {
1780
+ graph: namedNode('https://pod.example/alice/profile/.acr'),
1781
+ subject: namedNode('https://pod.example/alice/profile/card'),
1782
+ predicate: namedNode(`${ACP}accessControl`),
1783
+ object: { variable: 'accessControl' },
1784
+ },
1785
+ {
1786
+ graph: namedNode('https://pod.example/alice/profile/.acr'),
1787
+ subject: { variable: 'accessControl' },
1788
+ predicate: namedNode(`${ACP}apply`),
1789
+ object: namedNode('https://pod.example/alice/profile/card'),
1790
+ },
1791
+ {
1792
+ graph: namedNode('https://pod.example/alice/profile/.acr'),
1793
+ subject: { variable: 'accessControl' },
1794
+ predicate: namedNode(`${ACP}allow`),
1795
+ object: namedNode(`${ACP}Read`),
1796
+ },
1797
+ ],
1798
+ select: ['accessControl'],
1799
+ limit: 20,
1800
+ },
1801
+ expectedPlan: ['join-index', 'join-limit-pushdown'],
1802
+ },
1803
+ {
1804
+ name: 'profile inbox activity join query',
1805
+ resource: 'inboxNotification',
1806
+ purpose: 'WebID inbox lookup joins profile inbox relation with ActivityStreams inbox notification facts',
1807
+ minScale: 'medium',
1808
+ minReturnedRows: 1,
1809
+ query: {
1810
+ patterns: [
1811
+ {
1812
+ graph: namedNode('https://pod.example/alice/profile/card'),
1813
+ subject: namedNode('https://pod.example/alice/profile/card#me'),
1814
+ predicate: namedNode(LDP_INBOX),
1815
+ object: { variable: 'inbox' },
1816
+ },
1817
+ {
1818
+ graph: { $startsWith: 'https://pod.example/alice/inbox/' },
1819
+ subject: { variable: 'notification' },
1820
+ predicate: namedNode(RDF_TYPE),
1821
+ object: namedNode(`${AS}Activity`),
1822
+ },
1823
+ {
1824
+ graph: { $startsWith: 'https://pod.example/alice/inbox/' },
1825
+ subject: { variable: 'notification' },
1826
+ predicate: namedNode(`${AS}actor`),
1827
+ object: namedNode('https://pod.example/alice/profile/card#me'),
1828
+ },
1829
+ ],
1830
+ select: ['notification', 'inbox'],
1831
+ orderBy: [{ variable: 'notification' }],
1832
+ limit: 20,
1833
+ },
1834
+ expectedPlan: ['join-index', 'join-order-pushdown', 'join-limit-pushdown'],
1835
+ },
1836
+ {
1837
+ name: 'approval grant action match query',
1838
+ resource: 'approval',
1839
+ purpose: 'approval queue joins pending requests to matching autonomy grants by target workspace and action',
1840
+ minScale: 'medium',
1841
+ minReturnedRows: 1,
1842
+ query: {
1843
+ patterns: [
1844
+ {
1845
+ graph: { $startsWith: 'https://pod.example/alice/.data/approvals/' },
1846
+ subject: { variable: 'approval' },
1847
+ predicate: namedNode(RDF_TYPE),
1848
+ object: namedNode(`${UDFS}ApprovalRequest`),
1849
+ },
1850
+ {
1851
+ graph: { $startsWith: 'https://pod.example/alice/.data/approvals/' },
1852
+ subject: { variable: 'approval' },
1853
+ predicate: namedNode(`${UDFS}status`),
1854
+ object: literal('pending'),
1855
+ },
1856
+ {
1857
+ graph: { $startsWith: 'https://pod.example/alice/.data/approvals/' },
1858
+ subject: { variable: 'approval' },
1859
+ predicate: namedNode(`${ODRL}target`),
1860
+ object: { variable: 'workspace' },
1861
+ },
1862
+ {
1863
+ graph: { $startsWith: 'https://pod.example/alice/.data/approvals/' },
1864
+ subject: { variable: 'approval' },
1865
+ predicate: namedNode(`${ODRL}action`),
1866
+ object: { variable: 'action' },
1867
+ },
1868
+ {
1869
+ graph: { $startsWith: 'https://pod.example/alice/settings/autonomy/grants/' },
1870
+ subject: { variable: 'grant' },
1871
+ predicate: namedNode(`${ODRL}target`),
1872
+ object: { variable: 'workspace' },
1873
+ },
1874
+ {
1875
+ graph: { $startsWith: 'https://pod.example/alice/settings/autonomy/grants/' },
1876
+ subject: { variable: 'grant' },
1877
+ predicate: namedNode(`${ODRL}action`),
1878
+ object: { variable: 'action' },
1879
+ },
1880
+ {
1881
+ graph: { $startsWith: 'https://pod.example/alice/settings/autonomy/grants/' },
1882
+ subject: { variable: 'grant' },
1883
+ predicate: namedNode(`${UDFS}effect`),
1884
+ object: literal('allow'),
1885
+ },
1886
+ ],
1887
+ select: ['approval', 'grant', 'workspace', 'action'],
1888
+ orderBy: [
1889
+ {
1890
+ variable: 'approval',
1891
+ direction: 'asc',
1892
+ },
1893
+ ],
1894
+ limit: 20,
1895
+ },
1896
+ expectedPlan: ['join-index', 'join-order-pushdown', 'join-limit-pushdown'],
1897
+ },
1898
+ {
1899
+ name: 'favorite target chat join query',
1900
+ resource: 'favorite',
1901
+ purpose: 'favorite list joins model favorite target URI back to the chat resource for display hydration',
1902
+ minScale: 'small',
1903
+ minReturnedRows: 1,
1904
+ query: {
1905
+ patterns: [
1906
+ {
1907
+ graph: { $startsWith: 'https://pod.example/alice/.data/favorites/' },
1908
+ subject: { variable: 'favorite' },
1909
+ predicate: namedNode(`${UDFS}favoriteTarget`),
1910
+ object: { variable: 'chat' },
1911
+ },
1912
+ {
1913
+ graph: namedNode('https://pod.example/alice/.data/chat/default/index.ttl'),
1914
+ subject: { variable: 'chat' },
1915
+ predicate: namedNode(RDF_TYPE),
1916
+ object: namedNode(`${MEETING}LongChat`),
1917
+ },
1918
+ ],
1919
+ select: ['favorite', 'chat'],
1920
+ orderBy: [{ variable: 'favorite' }],
1921
+ limit: 20,
1922
+ },
1923
+ expectedPlan: ['join-index', 'join-order-pushdown', 'join-limit-pushdown'],
1924
+ },
1925
+ {
1926
+ name: 'contact entity profile join query',
1927
+ resource: 'contact',
1928
+ purpose: 'contact list joins vCard contact records to their represented entity URI',
1929
+ minScale: 'small',
1930
+ minReturnedRows: 1,
1931
+ query: {
1932
+ patterns: [
1933
+ {
1934
+ graph: { $startsWith: 'https://pod.example/alice/.data/contacts/' },
1935
+ subject: { variable: 'contact' },
1936
+ predicate: namedNode(FOAF_PRIMARY_TOPIC),
1937
+ object: { variable: 'entity' },
1938
+ },
1939
+ {
1940
+ graph: { $startsWith: 'https://pod.example/alice/.data/agents/' },
1941
+ subject: { variable: 'entity' },
1942
+ predicate: namedNode(RDF_TYPE),
1943
+ object: namedNode(FOAF_AGENT),
1944
+ },
1945
+ ],
1946
+ select: ['contact', 'entity'],
1947
+ orderBy: [{ variable: 'contact' }],
1948
+ limit: 20,
1949
+ },
1950
+ expectedPlan: ['join-index', 'join-order-pushdown', 'join-limit-pushdown'],
1951
+ },
1952
+ {
1953
+ name: 'settings owner category query',
1954
+ resource: 'settings',
1955
+ purpose: 'settings screens join owner/category/key/value fields under /settings without a full Pod scan',
1956
+ minScale: 'small',
1957
+ minReturnedRows: 1,
1958
+ query: {
1959
+ patterns: [
1960
+ {
1961
+ graph: { $startsWith: 'https://pod.example/alice/settings/' },
1962
+ subject: { variable: 'setting' },
1963
+ predicate: namedNode(RDF_TYPE),
1964
+ object: namedNode(SCHEMA_PROPERTY_VALUE),
1965
+ },
1966
+ {
1967
+ graph: { $startsWith: 'https://pod.example/alice/settings/' },
1968
+ subject: { variable: 'setting' },
1969
+ predicate: namedNode(DCT_CREATOR),
1970
+ object: namedNode('https://pod.example/alice/profile/card#me'),
1971
+ },
1972
+ {
1973
+ graph: { $startsWith: 'https://pod.example/alice/settings/' },
1974
+ subject: { variable: 'setting' },
1975
+ predicate: namedNode(DCT_TYPE),
1976
+ object: literal('ai'),
1977
+ },
1978
+ {
1979
+ graph: { $startsWith: 'https://pod.example/alice/settings/' },
1980
+ subject: { variable: 'setting' },
1981
+ predicate: namedNode(`${UDFS}settingKey`),
1982
+ object: { variable: 'key' },
1983
+ },
1984
+ {
1985
+ graph: { $startsWith: 'https://pod.example/alice/settings/' },
1986
+ subject: { variable: 'setting' },
1987
+ predicate: namedNode(`${UDFS}settingValue`),
1988
+ object: { variable: 'value' },
1989
+ },
1990
+ ],
1991
+ select: ['setting', 'key', 'value'],
1992
+ orderBy: [
1993
+ {
1994
+ variable: 'key',
1995
+ direction: 'asc',
1996
+ },
1997
+ ],
1998
+ limit: 20,
1999
+ },
2000
+ expectedPlan: ['join-index', 'join-order-pushdown', 'join-limit-pushdown'],
2001
+ },
2002
+ {
2003
+ name: 'settings owner category keyset query',
2004
+ resource: 'settings',
2005
+ purpose: 'settings screens keep key cursor, ordering, and pagination inside SQL self-join',
2006
+ minScale: 'small',
2007
+ minReturnedRows: 1,
2008
+ query: {
2009
+ patterns: [
2010
+ {
2011
+ graph: { $startsWith: 'https://pod.example/alice/settings/' },
2012
+ subject: { variable: 'setting' },
2013
+ predicate: namedNode(RDF_TYPE),
2014
+ object: namedNode(SCHEMA_PROPERTY_VALUE),
2015
+ },
2016
+ {
2017
+ graph: { $startsWith: 'https://pod.example/alice/settings/' },
2018
+ subject: { variable: 'setting' },
2019
+ predicate: namedNode(DCT_CREATOR),
2020
+ object: namedNode('https://pod.example/alice/profile/card#me'),
2021
+ },
2022
+ {
2023
+ graph: { $startsWith: 'https://pod.example/alice/settings/' },
2024
+ subject: { variable: 'setting' },
2025
+ predicate: namedNode(DCT_TYPE),
2026
+ object: literal('ai'),
2027
+ },
2028
+ {
2029
+ graph: { $startsWith: 'https://pod.example/alice/settings/' },
2030
+ subject: { variable: 'setting' },
2031
+ predicate: namedNode(`${UDFS}settingKey`),
2032
+ object: { variable: 'key' },
2033
+ },
2034
+ {
2035
+ graph: { $startsWith: 'https://pod.example/alice/settings/' },
2036
+ subject: { variable: 'setting' },
2037
+ predicate: namedNode(`${UDFS}settingValue`),
2038
+ object: { variable: 'value' },
2039
+ },
2040
+ ],
2041
+ filters: [
2042
+ {
2043
+ variable: 'key',
2044
+ operator: '$gt',
2045
+ value: literal('ai.defaultAssistant'),
2046
+ },
2047
+ ],
2048
+ select: ['setting', 'key', 'value'],
2049
+ orderBy: [
2050
+ {
2051
+ variable: 'key',
2052
+ direction: 'asc',
2053
+ },
2054
+ ],
2055
+ limit: 20,
2056
+ },
2057
+ expectedPlan: ['join-index', 'range-filter-pushdown', 'join-order-pushdown', 'join-limit-pushdown'],
2058
+ },
2059
+ {
2060
+ name: 'active session thread hydration query',
2061
+ resource: 'session',
2062
+ purpose: 'session manager hydrates active session, chat, thread, and token usage without pod-wide scans',
2063
+ minScale: 'small',
2064
+ minReturnedRows: 1,
2065
+ query: {
2066
+ patterns: [
2067
+ {
2068
+ graph: { $startsWith: 'https://pod.example/alice/.data/sessions/' },
2069
+ subject: { variable: 'session' },
2070
+ predicate: namedNode(RDF_TYPE),
2071
+ object: namedNode(`${UDFS}Session`),
2072
+ },
2073
+ {
2074
+ graph: { $startsWith: 'https://pod.example/alice/.data/sessions/' },
2075
+ subject: { variable: 'session' },
2076
+ predicate: namedNode(`${UDFS}actor`),
2077
+ object: namedNode('https://pod.example/alice/profile/card#me'),
2078
+ },
2079
+ {
2080
+ graph: { $startsWith: 'https://pod.example/alice/.data/sessions/' },
2081
+ subject: { variable: 'session' },
2082
+ predicate: namedNode(`${UDFS}sessionStatus`),
2083
+ object: literal('active'),
2084
+ },
2085
+ {
2086
+ graph: { $startsWith: 'https://pod.example/alice/.data/sessions/' },
2087
+ subject: { variable: 'session' },
2088
+ predicate: namedNode(`${UDFS}conversation`),
2089
+ object: { variable: 'chat' },
2090
+ },
2091
+ {
2092
+ graph: { $startsWith: 'https://pod.example/alice/.data/sessions/' },
2093
+ subject: { variable: 'session' },
2094
+ predicate: namedNode(`${UDFS}inThread`),
2095
+ object: { variable: 'thread' },
2096
+ },
2097
+ {
2098
+ graph: { $startsWith: 'https://pod.example/alice/.data/sessions/' },
2099
+ subject: { variable: 'session' },
2100
+ predicate: namedNode(`${UDFS}tokenUsage`),
2101
+ object: { variable: 'tokenUsage' },
2102
+ },
2103
+ {
2104
+ graph: namedNode('https://pod.example/alice/.data/chat/default/index.ttl'),
2105
+ subject: { variable: 'chat' },
2106
+ predicate: namedNode(RDF_TYPE),
2107
+ object: namedNode(`${MEETING}LongChat`),
2108
+ },
2109
+ {
2110
+ graph: namedNode('https://pod.example/alice/.data/chat/default/index.ttl'),
2111
+ subject: { variable: 'thread' },
2112
+ predicate: namedNode(RDF_TYPE),
2113
+ object: namedNode(`${SIOC}Thread`),
2114
+ },
2115
+ ],
2116
+ filters: [
2117
+ {
2118
+ variable: 'tokenUsage',
2119
+ operator: '$termType',
2120
+ value: 'numeric',
2121
+ },
2122
+ ],
2123
+ select: ['session', 'chat', 'thread', 'tokenUsage'],
2124
+ orderBy: [
2125
+ {
2126
+ variable: 'tokenUsage',
2127
+ direction: 'desc',
2128
+ },
2129
+ ],
2130
+ limit: 5,
2131
+ },
2132
+ expectedPlan: ['join-index', 'join-order-pushdown', 'join-limit-pushdown'],
2133
+ },
2134
+ {
2135
+ name: 'message reply chain query',
2136
+ resource: 'message',
2137
+ purpose: 'message detail views join replyTo and content facts across messages in the same date bucket',
2138
+ minScale: 'small',
2139
+ minReturnedRows: 1,
2140
+ query: {
2141
+ patterns: [
2142
+ {
2143
+ graph: { $startsWith: 'https://pod.example/alice/.data/chat/default/2026/05/' },
2144
+ subject: { variable: 'reply' },
2145
+ predicate: namedNode(`${UDFS}replyTo`),
2146
+ object: { variable: 'parent' },
2147
+ },
2148
+ {
2149
+ graph: { $startsWith: 'https://pod.example/alice/.data/chat/default/2026/05/' },
2150
+ subject: { variable: 'reply' },
2151
+ predicate: namedNode(SIOC_CONTENT),
2152
+ object: { variable: 'replyContent' },
2153
+ },
2154
+ {
2155
+ graph: { $startsWith: 'https://pod.example/alice/.data/chat/default/2026/05/' },
2156
+ subject: { variable: 'parent' },
2157
+ predicate: namedNode(SIOC_CONTENT),
2158
+ object: { variable: 'parentContent' },
2159
+ },
2160
+ ],
2161
+ select: ['reply', 'parent', 'replyContent', 'parentContent'],
2162
+ limit: 20,
2163
+ },
2164
+ expectedPlan: ['join-index', 'join-limit-pushdown'],
2165
+ },
2166
+ {
2167
+ name: 'routed message agent query',
2168
+ resource: 'message',
2169
+ purpose: 'multi-agent coordination joins routed messages to their agent/contact index',
2170
+ minScale: 'small',
2171
+ minReturnedRows: 1,
2172
+ query: {
2173
+ patterns: [
2174
+ {
2175
+ graph: { $startsWith: 'https://pod.example/alice/.data/chat/default/2026/05/' },
2176
+ subject: { variable: 'message' },
2177
+ predicate: namedNode(`${UDFS}routeTargetAgentId`),
2178
+ object: literal('secretary'),
2179
+ },
2180
+ {
2181
+ graph: { $startsWith: 'https://pod.example/alice/.data/chat/default/2026/05/' },
2182
+ subject: { variable: 'message' },
2183
+ predicate: namedNode(`${UDFS}coordinationId`),
2184
+ object: { variable: 'coordination' },
2185
+ },
2186
+ {
2187
+ graph: { $startsWith: 'https://pod.example/alice/.data/chat/default/2026/05/' },
2188
+ subject: { variable: 'message' },
2189
+ predicate: namedNode(FOAF_MAKER),
2190
+ object: { variable: 'maker' },
2191
+ },
2192
+ {
2193
+ graph: { $startsWith: 'https://pod.example/alice/.data/agents/' },
2194
+ subject: { variable: 'maker' },
2195
+ predicate: namedNode(RDF_TYPE),
2196
+ object: namedNode(FOAF_AGENT),
2197
+ },
2198
+ ],
2199
+ select: ['message', 'maker', 'coordination'],
2200
+ orderBy: [
2201
+ {
2202
+ variable: 'message',
2203
+ direction: 'asc',
2204
+ },
2205
+ ],
2206
+ limit: 20,
2207
+ },
2208
+ expectedPlan: ['join-index', 'join-order-pushdown', 'join-limit-pushdown'],
2209
+ },
2210
+ {
2211
+ name: 'audit approval policy trace query',
2212
+ resource: 'audit',
2213
+ purpose: 'audit timeline joins actor/session approval and grant policy relations for supervision views',
2214
+ minScale: 'medium',
2215
+ minReturnedRows: 1,
2216
+ query: {
2217
+ patterns: [
2218
+ {
2219
+ graph: { $startsWith: 'https://pod.example/alice/.data/audits/' },
2220
+ subject: { variable: 'audit' },
2221
+ predicate: namedNode(RDF_TYPE),
2222
+ object: namedNode(`${UDFS}AuditEntry`),
2223
+ },
2224
+ {
2225
+ graph: { $startsWith: 'https://pod.example/alice/.data/audits/' },
2226
+ subject: { variable: 'audit' },
2227
+ predicate: namedNode(`${UDFS}actor`),
2228
+ object: namedNode('https://pod.example/alice/profile/card#me'),
2229
+ },
2230
+ {
2231
+ graph: { $startsWith: 'https://pod.example/alice/.data/audits/' },
2232
+ subject: { variable: 'audit' },
2233
+ predicate: namedNode(`${UDFS}session`),
2234
+ object: { variable: 'session' },
2235
+ },
2236
+ {
2237
+ graph: { $startsWith: 'https://pod.example/alice/.data/audits/' },
2238
+ subject: { variable: 'audit' },
2239
+ predicate: namedNode(`${UDFS}approval`),
2240
+ object: { variable: 'approval' },
2241
+ },
2242
+ {
2243
+ graph: { $startsWith: 'https://pod.example/alice/.data/audits/' },
2244
+ subject: { variable: 'audit' },
2245
+ predicate: namedNode(`${UDFS}policy`),
2246
+ object: { variable: 'grant' },
2247
+ },
2248
+ {
2249
+ graph: { $startsWith: 'https://pod.example/alice/.data/audits/' },
2250
+ subject: { variable: 'audit' },
2251
+ predicate: namedNode(DCT_CREATED),
2252
+ object: { variable: 'createdAt' },
2253
+ },
2254
+ {
2255
+ graph: { $startsWith: 'https://pod.example/alice/.data/approvals/' },
2256
+ subject: { variable: 'approval' },
2257
+ predicate: namedNode(`${UDFS}status`),
2258
+ object: literal('pending'),
2259
+ },
2260
+ {
2261
+ graph: { $startsWith: 'https://pod.example/alice/settings/autonomy/grants/' },
2262
+ subject: { variable: 'grant' },
2263
+ predicate: namedNode(`${UDFS}effect`),
2264
+ object: literal('allow'),
2265
+ },
2266
+ ],
2267
+ select: ['audit', 'session', 'approval', 'grant', 'createdAt'],
2268
+ orderBy: [
2269
+ {
2270
+ variable: 'createdAt',
2271
+ direction: 'desc',
2272
+ },
2273
+ ],
2274
+ limit: 20,
2275
+ },
2276
+ expectedPlan: ['join-index', 'join-order-pushdown', 'join-limit-pushdown'],
2277
+ },
2278
+ {
2279
+ name: 'ai config embedding model query',
2280
+ resource: 'aiConfig',
2281
+ purpose: 'AI runtime config joins embedding model selection back to provider model metadata',
2282
+ minScale: 'small',
2283
+ minReturnedRows: 1,
2284
+ query: {
2285
+ patterns: [
2286
+ {
2287
+ graph: namedNode('https://pod.example/alice/settings/ai/config.ttl'),
2288
+ subject: { variable: 'config' },
2289
+ predicate: namedNode(RDF_TYPE),
2290
+ object: namedNode(`${XPOD_AI}AIConfig`),
2291
+ },
2292
+ {
2293
+ graph: namedNode('https://pod.example/alice/settings/ai/config.ttl'),
2294
+ subject: { variable: 'config' },
2295
+ predicate: namedNode(`${XPOD_AI}migrationStatus`),
2296
+ object: literal('ready'),
2297
+ },
2298
+ {
2299
+ graph: namedNode('https://pod.example/alice/settings/ai/config.ttl'),
2300
+ subject: { variable: 'config' },
2301
+ predicate: namedNode(`${XPOD_AI}embeddingModel`),
2302
+ object: { variable: 'model' },
2303
+ },
2304
+ {
2305
+ graph: namedNode('https://pod.example/alice/settings/providers/anthropic.ttl'),
2306
+ subject: { variable: 'model' },
2307
+ predicate: namedNode(`${XPOD_AI}isProvidedBy`),
2308
+ object: { variable: 'provider' },
2309
+ },
2310
+ {
2311
+ graph: namedNode('https://pod.example/alice/settings/providers/anthropic.ttl'),
2312
+ subject: { variable: 'model' },
2313
+ predicate: namedNode(`${XPOD_AI}status`),
2314
+ object: literal('active'),
2315
+ },
2316
+ ],
2317
+ select: ['config', 'model', 'provider'],
2318
+ limit: 10,
2319
+ },
2320
+ expectedPlan: ['join-index', 'join-limit-pushdown'],
2321
+ },
2322
+ {
2323
+ name: 'vector indexed file store query',
2324
+ resource: 'indexedFile',
2325
+ purpose: 'vector store settings join indexed files by chunking strategy and usage metadata',
2326
+ minScale: 'small',
2327
+ minReturnedRows: 1,
2328
+ query: {
2329
+ patterns: [
2330
+ {
2331
+ graph: namedNode('https://pod.example/alice/settings/ai/vector-stores.ttl'),
2332
+ subject: { variable: 'store' },
2333
+ predicate: namedNode(RDF_TYPE),
2334
+ object: namedNode(`${XPOD_AI}VectorStore`),
2335
+ },
2336
+ {
2337
+ graph: namedNode('https://pod.example/alice/settings/ai/vector-stores.ttl'),
2338
+ subject: { variable: 'store' },
2339
+ predicate: namedNode(`${XPOD_AI}status`),
2340
+ object: literal('active'),
2341
+ },
2342
+ {
2343
+ graph: namedNode('https://pod.example/alice/settings/ai/vector-stores.ttl'),
2344
+ subject: { variable: 'store' },
2345
+ predicate: namedNode(`${XPOD_AI}chunkingStrategy`),
2346
+ object: { variable: 'strategy' },
2347
+ },
2348
+ {
2349
+ graph: namedNode('https://pod.example/alice/settings/ai/indexed-files.ttl'),
2350
+ subject: { variable: 'file' },
2351
+ predicate: namedNode(RDF_TYPE),
2352
+ object: namedNode(`${XPOD_AI}IndexedFile`),
2353
+ },
2354
+ {
2355
+ graph: namedNode('https://pod.example/alice/settings/ai/indexed-files.ttl'),
2356
+ subject: { variable: 'file' },
2357
+ predicate: namedNode(`${XPOD_AI}status`),
2358
+ object: literal('indexed'),
2359
+ },
2360
+ {
2361
+ graph: namedNode('https://pod.example/alice/settings/ai/indexed-files.ttl'),
2362
+ subject: { variable: 'file' },
2363
+ predicate: namedNode(`${XPOD_AI}chunkingStrategy`),
2364
+ object: { variable: 'strategy' },
2365
+ },
2366
+ {
2367
+ graph: namedNode('https://pod.example/alice/settings/ai/indexed-files.ttl'),
2368
+ subject: { variable: 'file' },
2369
+ predicate: namedNode(`${XPOD_AI}usageBytes`),
2370
+ object: { variable: 'usageBytes' },
2371
+ },
2372
+ ],
2373
+ filters: [
2374
+ {
2375
+ variable: 'usageBytes',
2376
+ operator: '$termType',
2377
+ value: 'numeric',
2378
+ },
2379
+ ],
2380
+ select: ['store', 'file', 'strategy', 'usageBytes'],
2381
+ orderBy: [
2382
+ {
2383
+ variable: 'usageBytes',
2384
+ direction: 'desc',
2385
+ },
2386
+ ],
2387
+ limit: 20,
2388
+ },
2389
+ expectedPlan: ['join-index', 'join-order-pushdown', 'join-limit-pushdown'],
2390
+ },
2391
+ {
2392
+ name: 'message count by thread with having',
2393
+ resource: 'message',
2394
+ purpose: 'grouped message count uses SQL GROUP BY/HAVING before pagination',
2395
+ minScale: 'small',
2396
+ query: {
2397
+ patterns: [
2398
+ {
2399
+ graph: { $startsWith: 'https://pod.example/alice/.data/chat/default/' },
2400
+ subject: { variable: 'message' },
2401
+ predicate: namedNode(SIOC_HAS_MEMBER),
2402
+ object: { variable: 'thread' },
2403
+ },
2404
+ ],
2405
+ groupBy: ['thread'],
2406
+ aggregate: {
2407
+ type: 'count',
2408
+ as: 'count',
2409
+ variable: 'message',
2410
+ },
2411
+ having: [
2412
+ {
2413
+ variable: 'count',
2414
+ operator: '$gt',
2415
+ value: literal('2', namedNode('http://www.w3.org/2001/XMLSchema#integer')),
2416
+ },
2417
+ ],
2418
+ select: ['thread', 'count'],
2419
+ orderBy: [
2420
+ {
2421
+ variable: 'count',
2422
+ direction: 'desc',
2423
+ },
2424
+ ],
2425
+ limit: 1,
2426
+ },
2427
+ expectedPlan: ['group-count-index', 'having-pushdown', 'order', 'limit'],
2428
+ },
2429
+ {
2430
+ name: 'queued run priority numeric aggregate',
2431
+ resource: 'run',
2432
+ purpose: 'non-grouped numeric run priority aggregate stays inside SQL/RDF-3X aggregate execution',
2433
+ minScale: 'small',
2434
+ minReturnedRows: 1,
2435
+ query: {
2436
+ patterns: [
2437
+ {
2438
+ graph: { $startsWith: 'https://pod.example/alice/.data/task/default/' },
2439
+ subject: { variable: 'run' },
2440
+ predicate: namedNode(`${UDFS}status`),
2441
+ object: literal('queued'),
2442
+ },
2443
+ {
2444
+ graph: { $startsWith: 'https://pod.example/alice/.data/task/default/' },
2445
+ subject: { variable: 'run' },
2446
+ predicate: namedNode(`${UDFS}priority`),
2447
+ object: { variable: 'priority' },
2448
+ },
2449
+ ],
2450
+ filters: [
2451
+ {
2452
+ variable: 'priority',
2453
+ operator: '$termType',
2454
+ value: 'numeric',
2455
+ },
2456
+ ],
2457
+ aggregates: [
2458
+ {
2459
+ type: 'sum',
2460
+ as: 'priorityTotal',
2461
+ variable: 'priority',
2462
+ },
2463
+ {
2464
+ type: 'avg',
2465
+ as: 'priorityAvg',
2466
+ variable: 'priority',
2467
+ },
2468
+ {
2469
+ type: 'max',
2470
+ as: 'priorityMax',
2471
+ variable: 'priority',
2472
+ },
2473
+ ],
2474
+ select: ['priorityTotal', 'priorityAvg', 'priorityMax'],
2475
+ },
2476
+ expectedPlan: ['join-aggregate-index'],
2477
+ },
2478
+ {
2479
+ name: 'message score by thread numeric aggregate',
2480
+ resource: 'message',
2481
+ purpose: 'group-prefix grouped numeric message score aggregate stays on RDF-3X instead of row-materializing facts',
2482
+ minScale: 'small',
2483
+ minReturnedRows: 1,
2484
+ query: {
2485
+ patterns: [
2486
+ {
2487
+ graph: { $startsWith: 'https://pod.example/alice/.data/chat/default/' },
2488
+ subject: { variable: 'message' },
2489
+ predicate: namedNode(SIOC_HAS_MEMBER),
2490
+ object: { variable: 'thread' },
2491
+ },
2492
+ {
2493
+ graph: { $startsWith: 'https://pod.example/alice/.data/chat/default/' },
2494
+ subject: { variable: 'message' },
2495
+ predicate: namedNode(`${UDFS}score`),
2496
+ object: { variable: 'score' },
2497
+ },
2498
+ ],
2499
+ filters: [
2500
+ {
2501
+ variable: 'score',
2502
+ operator: '$termType',
2503
+ value: 'numeric',
2504
+ },
2505
+ ],
2506
+ groupBy: ['thread'],
2507
+ aggregates: [
2508
+ {
2509
+ type: 'count',
2510
+ as: 'count',
2511
+ variable: 'message',
2512
+ },
2513
+ {
2514
+ type: 'sum',
2515
+ as: 'scoreTotal',
2516
+ variable: 'score',
2517
+ },
2518
+ {
2519
+ type: 'avg',
2520
+ as: 'scoreAvg',
2521
+ variable: 'score',
2522
+ },
2523
+ ],
2524
+ having: [
2525
+ {
2526
+ variable: 'scoreTotal',
2527
+ operator: '$gt',
2528
+ value: literal('4', namedNode('http://www.w3.org/2001/XMLSchema#integer')),
2529
+ },
2530
+ ],
2531
+ select: ['thread', 'count', 'scoreTotal', 'scoreAvg'],
2532
+ orderBy: [
2533
+ {
2534
+ variable: 'scoreTotal',
2535
+ direction: 'desc',
2536
+ },
2537
+ ],
2538
+ limit: 1,
2539
+ },
2540
+ expectedPlan: ['numeric-aggregate'],
2541
+ },
2542
+ {
2543
+ name: 'message join count distinct',
2544
+ resource: 'message',
2545
+ purpose: 'message/thread BGP aggregate count stays on the PostgreSQL RDF-3X count path',
2546
+ minScale: 'small',
2547
+ query: {
2548
+ patterns: [
2549
+ {
2550
+ graph: { $startsWith: 'https://pod.example/alice/.data/chat/default/' },
2551
+ subject: { variable: 'message' },
2552
+ predicate: namedNode(RDF_TYPE),
2553
+ object: namedNode(`${MEETING}Message`),
2554
+ },
2555
+ {
2556
+ graph: { $startsWith: 'https://pod.example/alice/.data/chat/default/' },
2557
+ subject: { variable: 'message' },
2558
+ predicate: namedNode(SIOC_HAS_MEMBER),
2559
+ object: { variable: 'thread' },
2560
+ },
2561
+ ],
2562
+ aggregates: [
2563
+ {
2564
+ type: 'count',
2565
+ as: 'messageCount',
2566
+ variable: 'message',
2567
+ },
2568
+ {
2569
+ type: 'count',
2570
+ as: 'threadCount',
2571
+ variable: 'thread',
2572
+ distinct: true,
2573
+ },
2574
+ ],
2575
+ },
2576
+ expectedPlan: ['join-count-index'],
2577
+ },
2578
+ ];
2579
+ exports.rdfModelsSearchFusionQueryBenchmarkCases = [
2580
+ {
2581
+ name: 'agent context text vector fusion query',
2582
+ resource: 'message',
2583
+ purpose: 'agent context search intersects text chunks, vector chunks, and structured message/thread/workspace RDF facts, then reranks by a fused score',
2584
+ minScale: 'small',
2585
+ minReturnedRows: 1,
2586
+ query: {
2587
+ patterns: [
2588
+ {
2589
+ graph: { $startsWith: 'https://pod.example/alice/.data/chat/default/2026/05/' },
2590
+ subject: { variable: 'message' },
2591
+ predicate: namedNode(RDF_TYPE),
2592
+ object: namedNode(`${MEETING}Message`),
2593
+ },
2594
+ {
2595
+ graph: { $startsWith: 'https://pod.example/alice/.data/chat/default/2026/05/' },
2596
+ subject: { variable: 'message' },
2597
+ predicate: namedNode(SIOC_HAS_MEMBER),
2598
+ object: { variable: 'thread' },
2599
+ },
2600
+ {
2601
+ graph: { $startsWith: 'https://pod.example/alice/.data/chat/default/2026/05/' },
2602
+ subject: { variable: 'message' },
2603
+ predicate: namedNode(`${UDFS}workspace`),
2604
+ object: namedNode(WORKSPACE),
2605
+ },
2606
+ ],
2607
+ textSearch: [
2608
+ {
2609
+ query: 'runtime approvals',
2610
+ scope: {
2611
+ workspace: WORKSPACE,
2612
+ sourcePrefix: `${DATA}/chat/default/`,
2613
+ accessBasePath: `${DATA}/chat/default/`,
2614
+ },
2615
+ source: 'message',
2616
+ content: 'textContent',
2617
+ score: 'textScore',
2618
+ },
2619
+ ],
2620
+ vectorSearch: [
2621
+ {
2622
+ embedding: [0.95, 0.2, 0.05],
2623
+ metric: 'cosine',
2624
+ vectorModel: RDF_MODELS_SEARCH_VECTOR_MODEL,
2625
+ scope: {
2626
+ workspace: WORKSPACE,
2627
+ sourcePrefix: `${DATA}/chat/default/`,
2628
+ accessBasePath: `${DATA}/chat/default/`,
2629
+ },
2630
+ source: 'message',
2631
+ content: 'vectorContent',
2632
+ score: 'vectorScore',
2633
+ distance: 'vectorDistance',
2634
+ model: 'embeddingModel',
2635
+ },
2636
+ ],
2637
+ binds: [
2638
+ {
2639
+ variable: 'fusionScore',
2640
+ expression: {
2641
+ type: 'add',
2642
+ expressions: [
2643
+ {
2644
+ type: 'multiply',
2645
+ expressions: [
2646
+ { type: 'numericValue', expression: { type: 'variable', variable: 'textScore' } },
2647
+ { type: 'term', term: literal('0.55', namedNode(XSD_DECIMAL)) },
2648
+ ],
2649
+ },
2650
+ {
2651
+ type: 'multiply',
2652
+ expressions: [
2653
+ { type: 'numericValue', expression: { type: 'variable', variable: 'vectorScore' } },
2654
+ { type: 'term', term: literal('0.45', namedNode(XSD_DECIMAL)) },
2655
+ ],
2656
+ },
2657
+ ],
2658
+ },
2659
+ },
2660
+ ],
2661
+ select: ['message', 'thread', 'textContent', 'textScore', 'vectorContent', 'vectorScore', 'vectorDistance', 'fusionScore'],
2662
+ orderBy: [
2663
+ { variable: 'fusionScore', direction: 'desc' },
2664
+ { variable: 'message' },
2665
+ ],
2666
+ limit: 10,
2667
+ },
2668
+ expectedPlan: ['text-search-source', 'vector-search-source', 'search-rdf-join', 'planner-source-estimates', 'fusion-rank-inputs', 'fusion-rank-weights', 'fusion-rank-tiebreaker', 'fusion-hard-filters-before-rank', 'search-score-rerank'],
2669
+ },
2670
+ {
2671
+ name: 'broad agent context text vector fusion query',
2672
+ resource: 'message',
2673
+ purpose: 'broad agent context search keeps text/vector/RDF/path/ACL candidate sources visible when many chunks match before final top-k',
2674
+ minScale: 'small',
2675
+ minReturnedRows: 10,
2676
+ query: {
2677
+ patterns: [
2678
+ {
2679
+ graph: { $startsWith: 'https://pod.example/alice/.data/chat/default/2026/05/' },
2680
+ subject: { variable: 'message' },
2681
+ predicate: namedNode(RDF_TYPE),
2682
+ object: namedNode(`${MEETING}Message`),
2683
+ },
2684
+ {
2685
+ graph: { $startsWith: 'https://pod.example/alice/.data/chat/default/2026/05/' },
2686
+ subject: { variable: 'message' },
2687
+ predicate: namedNode(SIOC_HAS_MEMBER),
2688
+ object: { variable: 'thread' },
2689
+ },
2690
+ {
2691
+ graph: { $startsWith: 'https://pod.example/alice/.data/chat/default/2026/05/' },
2692
+ subject: { variable: 'message' },
2693
+ predicate: namedNode(`${UDFS}workspace`),
2694
+ object: namedNode(WORKSPACE),
2695
+ },
2696
+ ],
2697
+ textSearch: [
2698
+ {
2699
+ query: 'candidate retrieval',
2700
+ scope: {
2701
+ workspace: WORKSPACE,
2702
+ sourcePrefix: `${DATA}/chat/default/`,
2703
+ accessBasePath: `${DATA}/chat/default/`,
2704
+ },
2705
+ source: 'message',
2706
+ content: 'textContent',
2707
+ score: 'textScore',
2708
+ },
2709
+ ],
2710
+ vectorSearch: [
2711
+ {
2712
+ embedding: [0.82, 0.48, 0.12],
2713
+ metric: 'cosine',
2714
+ vectorModel: RDF_MODELS_SEARCH_VECTOR_MODEL,
2715
+ scope: {
2716
+ workspace: WORKSPACE,
2717
+ sourcePrefix: `${DATA}/chat/default/`,
2718
+ accessBasePath: `${DATA}/chat/default/`,
2719
+ },
2720
+ source: 'message',
2721
+ content: 'vectorContent',
2722
+ score: 'vectorScore',
2723
+ distance: 'vectorDistance',
2724
+ model: 'embeddingModel',
2725
+ },
2726
+ ],
2727
+ binds: [
2728
+ {
2729
+ variable: 'fusionScore',
2730
+ expression: {
2731
+ type: 'add',
2732
+ expressions: [
2733
+ {
2734
+ type: 'multiply',
2735
+ expressions: [
2736
+ { type: 'numericValue', expression: { type: 'variable', variable: 'textScore' } },
2737
+ { type: 'term', term: literal('0.55', namedNode(XSD_DECIMAL)) },
2738
+ ],
2739
+ },
2740
+ {
2741
+ type: 'multiply',
2742
+ expressions: [
2743
+ { type: 'numericValue', expression: { type: 'variable', variable: 'vectorScore' } },
2744
+ { type: 'term', term: literal('0.45', namedNode(XSD_DECIMAL)) },
2745
+ ],
2746
+ },
2747
+ ],
2748
+ },
2749
+ },
2750
+ ],
2751
+ select: ['message', 'thread', 'textContent', 'textScore', 'vectorContent', 'vectorScore', 'vectorDistance', 'fusionScore'],
2752
+ orderBy: [
2753
+ { variable: 'fusionScore', direction: 'desc' },
2754
+ { variable: 'message' },
2755
+ ],
2756
+ limit: 10,
2757
+ },
2758
+ expectedPlan: ['text-search-source', 'vector-search-source', 'search-rdf-join', 'planner-source-estimates', 'fusion-rank-inputs', 'fusion-rank-weights', 'fusion-rank-tiebreaker', 'fusion-hard-filters-before-rank', 'search-score-rerank'],
2759
+ },
2760
+ ];
2761
+ exports.rdfModelsPostgresMaterializedQueryBenchmarkCases = [
2762
+ postgresMaterializedQueryBenchmarkCase('latest message by thread query', {
2763
+ name: 'materialized latest message by thread query',
2764
+ purpose: 'high-frequency chat timeline view reuses the materialized latest-message result after warmup',
2765
+ materialized: {
2766
+ key: 'models/chat/default/thread_1/latest-message',
2767
+ version: '2026-05-18',
2768
+ },
2769
+ }),
2770
+ postgresMaterializedQueryBenchmarkCase('thread context window query', {
2771
+ name: 'materialized thread context window query',
2772
+ purpose: 'agent context assembly reuses a materialized thread window after warmup',
2773
+ materialized: {
2774
+ key: 'models/chat/default/thread_1/context-window',
2775
+ version: '2026-05-18',
2776
+ },
2777
+ }),
2778
+ postgresMaterializedQueryBenchmarkCase('run steps by run query', {
2779
+ name: 'materialized run steps by run query',
2780
+ purpose: 'run detail views reuse the materialized run-step list after warmup',
2781
+ materialized: {
2782
+ key: 'models/task/default/run_1/steps',
2783
+ version: '2026-05-18',
2784
+ },
2785
+ }),
2786
+ postgresMaterializedQueryBenchmarkCase('task materialization active due query', {
2787
+ name: 'materialized task materialization active due query',
2788
+ purpose: 'scheduler due-task polling reuses a cutoff-scoped materialized active schedule view after warmup',
2789
+ materialized: {
2790
+ key: 'models/task/default/due-schedules/2026-05-18T01:30:00.000Z',
2791
+ version: 'cutoff:2026-05-18T01:30:00.000Z',
2792
+ },
2793
+ }),
2794
+ postgresMaterializedQueryBenchmarkCase('provider model credential join query', {
2795
+ name: 'materialized provider model credential join query',
2796
+ purpose: 'settings/provider startup views reuse a materialized provider-model-credential relation after warmup',
2797
+ materialized: {
2798
+ key: 'models/settings/providers/anthropic/model-credentials',
2799
+ version: 'v1',
2800
+ },
2801
+ }),
2802
+ postgresMaterializedQueryBenchmarkCase('settings owner category keyset query', {
2803
+ name: 'materialized settings owner category keyset query',
2804
+ purpose: 'settings list drill-down reuses owner/category/keyset pagination after warmup',
2805
+ materialized: {
2806
+ key: 'models/settings/owner-category/keyset-ai',
2807
+ version: 'cursor:ai.defaultAssistant',
2808
+ },
2809
+ }),
2810
+ postgresMaterializedQueryBenchmarkCase('active session thread hydration query', {
2811
+ name: 'materialized active session thread hydration query',
2812
+ purpose: 'agent session drill-down reuses active session/chat/thread hydration after warmup',
2813
+ materialized: {
2814
+ key: 'models/agent-context/active-session-thread-usage',
2815
+ version: 'v1',
2816
+ },
2817
+ }),
2818
+ postgresMaterializedQueryBenchmarkCase('ai config embedding model query', {
2819
+ name: 'materialized ai config embedding model query',
2820
+ purpose: 'AI settings drill-down reuses embedding model/provider hydration after warmup',
2821
+ materialized: {
2822
+ key: 'models/settings/ai/config/embedding-model',
2823
+ version: 'v1',
2824
+ },
2825
+ }),
2826
+ postgresMaterializedQueryBenchmarkCase('vector indexed file store query', {
2827
+ name: 'materialized vector indexed file store query',
2828
+ purpose: 'vector store drill-down reuses indexed-file/store metadata join after warmup',
2829
+ materialized: {
2830
+ key: 'models/settings/ai/vector-store/indexed-files',
2831
+ version: 'v1',
2832
+ },
2833
+ }),
2834
+ ];
2835
+ exports.rdfModelsPostgresQueryBenchmarkCases = [
2836
+ ...exports.rdfModelsQueryBenchmarkCases,
2837
+ ...exports.rdfModelsPostgresMaterializedQueryBenchmarkCases,
2838
+ ];
2839
+ function postgresMaterializedQueryBenchmarkCase(baseName, options) {
2840
+ const base = exports.rdfModelsQueryBenchmarkCases.find((testCase) => testCase.name === baseName);
2841
+ if (!base) {
2842
+ throw new Error(`Unknown RDF models query benchmark case: ${baseName}`);
2843
+ }
2844
+ return {
2845
+ ...base,
2846
+ name: options.name,
2847
+ purpose: options.purpose,
2848
+ minReturnedRows: base.minReturnedRows ?? 1,
2849
+ benchmarkCache: 'preserve',
2850
+ minWarmupIterations: 1,
2851
+ query: {
2852
+ ...base.query,
2853
+ cache: {
2854
+ ...(base.query.cache ?? {}),
2855
+ materialized: options.materialized,
2856
+ },
2857
+ },
2858
+ expectedPlan: ['materialized-cache-hit', 'query-template-cache-hit', ...base.expectedPlan],
2859
+ };
2860
+ }
2861
+ exports.rdfModelsExtremeBenchmarkCases = [
2862
+ {
2863
+ name: 'extreme month message score range scan',
2864
+ resource: 'message',
2865
+ purpose: 'large month graph-prefix numeric score scan stresses graph membership plus object range pushdown',
2866
+ minScale: 'medium',
2867
+ query: {
2868
+ pattern: {
2869
+ predicate: namedNode(`${UDFS}score`),
2870
+ object: { $gte: literal('50', namedNode(XSD_INTEGER)) },
2871
+ graph: { $startsWith: `${DATA}/chat/default/2026/05/` },
2872
+ },
2873
+ options: { order: ['subject'], limit: 500 },
2874
+ },
2875
+ expectedPlan: ['graph-scope', 'predicate-object-range-filter', 'order', 'limit'],
2876
+ },
2877
+ {
2878
+ name: 'extreme month message text scan',
2879
+ resource: 'message',
2880
+ purpose: 'large graph-prefix text scan validates that object text lookup reconnects through RDF subjects',
2881
+ minScale: 'medium',
2882
+ query: {
2883
+ pattern: {
2884
+ predicate: namedNode(SIOC_CONTENT),
2885
+ object: { $contains: 'synthetic searchable message' },
2886
+ graph: { $startsWith: `${DATA}/chat/default/2026/05/` },
2887
+ },
2888
+ options: { order: ['subject'], limit: 500 },
2889
+ },
2890
+ expectedPlan: ['text-index', 'rdf-subject-join', 'order', 'limit'],
2891
+ },
2892
+ ];
2893
+ exports.rdfModelsExtremeQueryBenchmarkCases = [
2894
+ {
2895
+ name: 'extreme message eight-pattern star query',
2896
+ resource: 'message',
2897
+ purpose: '8-pattern subject-star BGP stresses deep custom-index joins before pagination',
2898
+ minScale: 'medium',
2899
+ minReturnedRows: 100,
2900
+ query: {
2901
+ patterns: [
2902
+ {
2903
+ graph: { $startsWith: `${DATA}/chat/default/2026/05/` },
2904
+ subject: { variable: 'message' },
2905
+ predicate: namedNode(RDF_TYPE),
2906
+ object: namedNode(`${MEETING}Message`),
2907
+ },
2908
+ {
2909
+ graph: { $startsWith: `${DATA}/chat/default/2026/05/` },
2910
+ subject: { variable: 'message' },
2911
+ predicate: namedNode(SIOC_HAS_MEMBER),
2912
+ object: { variable: 'thread' },
2913
+ },
2914
+ {
2915
+ graph: { $startsWith: `${DATA}/chat/default/2026/05/` },
2916
+ subject: { variable: 'message' },
2917
+ predicate: namedNode(DCT_CREATED),
2918
+ object: { variable: 'createdAt' },
2919
+ },
2920
+ {
2921
+ graph: { $startsWith: `${DATA}/chat/default/2026/05/` },
2922
+ subject: { variable: 'message' },
2923
+ predicate: namedNode(DCT_MODIFIED),
2924
+ object: { variable: 'modifiedAt' },
2925
+ },
2926
+ {
2927
+ graph: { $startsWith: `${DATA}/chat/default/2026/05/` },
2928
+ subject: { variable: 'message' },
2929
+ predicate: namedNode(`${UDFS}score`),
2930
+ object: { variable: 'score' },
2931
+ },
2932
+ {
2933
+ graph: { $startsWith: `${DATA}/chat/default/2026/05/` },
2934
+ subject: { variable: 'message' },
2935
+ predicate: namedNode(`${UDFS}rank`),
2936
+ object: { variable: 'rank' },
2937
+ },
2938
+ {
2939
+ graph: { $startsWith: `${DATA}/chat/default/2026/05/` },
2940
+ subject: { variable: 'message' },
2941
+ predicate: namedNode(`${UDFS}status`),
2942
+ object: literal('indexed'),
2943
+ },
2944
+ {
2945
+ graph: { $startsWith: `${DATA}/chat/default/2026/05/` },
2946
+ subject: { variable: 'message' },
2947
+ predicate: namedNode(`${UDFS}workspace`),
2948
+ object: namedNode(WORKSPACE),
2949
+ },
2950
+ ],
2951
+ select: ['message', 'thread', 'createdAt', 'score'],
2952
+ orderBy: [
2953
+ {
2954
+ variable: 'createdAt',
2955
+ direction: 'desc',
2956
+ },
2957
+ ],
2958
+ limit: 100,
2959
+ },
2960
+ expectedPlan: ['join-index', 'subject-star-join', 'join-order-pushdown', 'join-limit-pushdown'],
2961
+ },
2962
+ {
2963
+ name: 'extreme message large VALUES thread query',
2964
+ resource: 'message',
2965
+ purpose: 'large VALUES-constrained fanout join checks native tuple-values pushdown against RDF-3X baseline',
2966
+ minScale: 'medium',
2967
+ minReturnedRows: 100,
2968
+ query: {
2969
+ patterns: [
2970
+ {
2971
+ graph: { $startsWith: `${DATA}/chat/default/2026/05/` },
2972
+ subject: { variable: 'message' },
2973
+ predicate: namedNode(SIOC_HAS_MEMBER),
2974
+ object: { variable: 'thread' },
2975
+ },
2976
+ {
2977
+ graph: { $startsWith: `${DATA}/chat/default/2026/05/` },
2978
+ subject: { variable: 'message' },
2979
+ predicate: namedNode(DCT_CREATED),
2980
+ object: { variable: 'createdAt' },
2981
+ },
2982
+ ],
2983
+ values: [
2984
+ {
2985
+ variables: ['thread'],
2986
+ rows: syntheticThreadValueRows(32),
2987
+ },
2988
+ ],
2989
+ select: ['message', 'thread', 'createdAt'],
2990
+ orderBy: [
2991
+ {
2992
+ variable: 'createdAt',
2993
+ direction: 'desc',
2994
+ },
2995
+ ],
2996
+ limit: 500,
2997
+ },
2998
+ expectedPlan: ['join-index', 'values-join-pushdown'],
2999
+ },
3000
+ {
3001
+ name: 'extreme message count distinct thread query',
3002
+ resource: 'message',
3003
+ purpose: 'large fanout COUNT plus COUNT DISTINCT tests the hard aggregate path where native numeric aggregate must not over-claim',
3004
+ minScale: 'medium',
3005
+ minReturnedRows: 1,
3006
+ query: {
3007
+ patterns: [
3008
+ {
3009
+ graph: { $startsWith: `${DATA}/chat/default/2026/05/` },
3010
+ subject: { variable: 'message' },
3011
+ predicate: namedNode(RDF_TYPE),
3012
+ object: namedNode(`${MEETING}Message`),
3013
+ },
3014
+ {
3015
+ graph: { $startsWith: `${DATA}/chat/default/2026/05/` },
3016
+ subject: { variable: 'message' },
3017
+ predicate: namedNode(SIOC_HAS_MEMBER),
3018
+ object: { variable: 'thread' },
3019
+ },
3020
+ ],
3021
+ aggregates: [
3022
+ {
3023
+ type: 'count',
3024
+ as: 'messageCount',
3025
+ variable: 'message',
3026
+ },
3027
+ {
3028
+ type: 'count',
3029
+ as: 'threadCount',
3030
+ variable: 'thread',
3031
+ distinct: true,
3032
+ },
3033
+ ],
3034
+ select: ['messageCount', 'threadCount'],
3035
+ },
3036
+ expectedPlan: ['join-count-index'],
3037
+ },
3038
+ {
3039
+ name: 'extreme message grouped count by thread query',
3040
+ resource: 'message',
3041
+ purpose: 'large fanout grouped count validates thread-level scheduler-style aggregation under HAVING/ORDER/LIMIT',
3042
+ minScale: 'medium',
3043
+ minReturnedRows: 10,
3044
+ query: {
3045
+ patterns: [
3046
+ {
3047
+ graph: { $startsWith: `${DATA}/chat/default/2026/05/` },
3048
+ subject: { variable: 'message' },
3049
+ predicate: namedNode(SIOC_HAS_MEMBER),
3050
+ object: { variable: 'thread' },
3051
+ },
3052
+ ],
3053
+ groupBy: ['thread'],
3054
+ aggregates: [
3055
+ {
3056
+ type: 'count',
3057
+ as: 'messageCount',
3058
+ variable: 'message',
3059
+ },
3060
+ ],
3061
+ having: [
3062
+ {
3063
+ variable: 'messageCount',
3064
+ operator: '$gt',
3065
+ value: literal('5', namedNode(XSD_INTEGER)),
3066
+ },
3067
+ ],
3068
+ select: ['thread', 'messageCount'],
3069
+ orderBy: [
3070
+ {
3071
+ variable: 'messageCount',
3072
+ direction: 'desc',
3073
+ },
3074
+ {
3075
+ variable: 'thread',
3076
+ direction: 'asc',
3077
+ },
3078
+ ],
3079
+ limit: 10,
3080
+ },
3081
+ expectedPlan: ['group-count-index', 'having-pushdown', 'order', 'limit'],
3082
+ },
3083
+ {
3084
+ name: 'extreme message grouped numeric aggregate by thread query',
3085
+ resource: 'message',
3086
+ purpose: 'large fanout grouped numeric aggregate is the primary pg-custom-index native aggregate proving ground',
3087
+ minScale: 'medium',
3088
+ minReturnedRows: 10,
3089
+ query: {
3090
+ patterns: [
3091
+ {
3092
+ graph: { $startsWith: `${DATA}/chat/default/2026/05/` },
3093
+ subject: { variable: 'message' },
3094
+ predicate: namedNode(SIOC_HAS_MEMBER),
3095
+ object: { variable: 'thread' },
3096
+ },
3097
+ {
3098
+ graph: { $startsWith: `${DATA}/chat/default/2026/05/` },
3099
+ subject: { variable: 'message' },
3100
+ predicate: namedNode(`${UDFS}score`),
3101
+ object: { variable: 'score' },
3102
+ },
3103
+ {
3104
+ graph: { $startsWith: `${DATA}/chat/default/2026/05/` },
3105
+ subject: { variable: 'message' },
3106
+ predicate: namedNode(`${UDFS}status`),
3107
+ object: literal('indexed'),
3108
+ },
3109
+ ],
3110
+ filters: [
3111
+ {
3112
+ variable: 'score',
3113
+ operator: '$termType',
3114
+ value: 'numeric',
3115
+ },
3116
+ ],
3117
+ groupBy: ['thread'],
3118
+ aggregates: [
3119
+ {
3120
+ type: 'count',
3121
+ as: 'messageCount',
3122
+ variable: 'message',
3123
+ },
3124
+ {
3125
+ type: 'sum',
3126
+ as: 'scoreTotal',
3127
+ variable: 'score',
3128
+ },
3129
+ {
3130
+ type: 'avg',
3131
+ as: 'scoreAvg',
3132
+ variable: 'score',
3133
+ },
3134
+ {
3135
+ type: 'max',
3136
+ as: 'scoreMax',
3137
+ variable: 'score',
3138
+ },
3139
+ ],
3140
+ having: [
3141
+ {
3142
+ variable: 'scoreTotal',
3143
+ operator: '$gt',
3144
+ value: literal('100', namedNode(XSD_INTEGER)),
3145
+ },
3146
+ ],
3147
+ select: ['thread', 'messageCount', 'scoreTotal', 'scoreAvg', 'scoreMax'],
3148
+ orderBy: [
3149
+ {
3150
+ variable: 'scoreTotal',
3151
+ direction: 'desc',
3152
+ },
3153
+ {
3154
+ variable: 'thread',
3155
+ direction: 'asc',
3156
+ },
3157
+ ],
3158
+ limit: 10,
3159
+ },
3160
+ expectedPlan: ['group-aggregate-index', 'having-pushdown', 'order', 'limit'],
3161
+ },
3162
+ {
3163
+ name: 'extreme native exact graph eight-pattern join query',
3164
+ resource: 'message',
3165
+ purpose: 'high fanout exact-graph 8-pattern BGP is the custom-index native row-stream gate',
3166
+ minScale: 'medium',
3167
+ minReturnedRows: 200,
3168
+ query: {
3169
+ patterns: [
3170
+ {
3171
+ graph: namedNode(NATIVE_STRESS_GRAPH),
3172
+ subject: { variable: 'message' },
3173
+ predicate: namedNode(RDF_TYPE),
3174
+ object: namedNode(`${MEETING}Message`),
3175
+ },
3176
+ {
3177
+ graph: namedNode(NATIVE_STRESS_GRAPH),
3178
+ subject: { variable: 'message' },
3179
+ predicate: namedNode(SIOC_HAS_MEMBER),
3180
+ object: { variable: 'thread' },
3181
+ },
3182
+ {
3183
+ graph: namedNode(NATIVE_STRESS_GRAPH),
3184
+ subject: { variable: 'message' },
3185
+ predicate: namedNode(DCT_CREATED),
3186
+ object: { variable: 'createdAt' },
3187
+ },
3188
+ {
3189
+ graph: namedNode(NATIVE_STRESS_GRAPH),
3190
+ subject: { variable: 'message' },
3191
+ predicate: namedNode(DCT_MODIFIED),
3192
+ object: { variable: 'modifiedAt' },
3193
+ },
3194
+ {
3195
+ graph: namedNode(NATIVE_STRESS_GRAPH),
3196
+ subject: { variable: 'message' },
3197
+ predicate: namedNode(`${UDFS}score`),
3198
+ object: { variable: 'score' },
3199
+ },
3200
+ {
3201
+ graph: namedNode(NATIVE_STRESS_GRAPH),
3202
+ subject: { variable: 'message' },
3203
+ predicate: namedNode(`${UDFS}rank`),
3204
+ object: { variable: 'rank' },
3205
+ },
3206
+ {
3207
+ graph: namedNode(NATIVE_STRESS_GRAPH),
3208
+ subject: { variable: 'message' },
3209
+ predicate: namedNode(`${UDFS}status`),
3210
+ object: literal('indexed'),
3211
+ },
3212
+ {
3213
+ graph: namedNode(NATIVE_STRESS_GRAPH),
3214
+ subject: { variable: 'message' },
3215
+ predicate: namedNode(`${UDFS}workspace`),
3216
+ object: namedNode(WORKSPACE),
3217
+ },
3218
+ ],
3219
+ select: ['message', 'thread', 'createdAt', 'score'],
3220
+ limit: 256,
3221
+ },
3222
+ expectedPlan: ['join-index', 'join-limit-pushdown'],
3223
+ },
3224
+ {
3225
+ name: 'extreme native exact graph ordered-page query',
3226
+ resource: 'message',
3227
+ purpose: 'high fanout exact-graph ordered page checks native BGP row stream plus projected order pagination',
3228
+ minScale: 'medium',
3229
+ minReturnedRows: 100,
3230
+ query: {
3231
+ patterns: [
3232
+ {
3233
+ graph: namedNode(NATIVE_STRESS_GRAPH),
3234
+ subject: { variable: 'message' },
3235
+ predicate: namedNode(`${UDFS}status`),
3236
+ object: literal('indexed'),
415
3237
  },
416
3238
  {
417
- graph: { $startsWith: 'https://pod.example/alice/.data/task/default/' },
418
- subject: { variable: 'run' },
3239
+ graph: namedNode(NATIVE_STRESS_GRAPH),
3240
+ subject: { variable: 'message' },
419
3241
  predicate: namedNode(DCT_CREATED),
420
3242
  object: { variable: 'createdAt' },
421
3243
  },
422
3244
  ],
423
- select: ['run', 'createdAt'],
3245
+ select: ['message', 'createdAt'],
424
3246
  orderBy: [
425
3247
  {
426
3248
  variable: 'createdAt',
427
- direction: 'asc',
3249
+ direction: 'desc',
428
3250
  },
429
3251
  ],
430
- limit: 1,
3252
+ limit: 128,
431
3253
  },
432
3254
  expectedPlan: ['join-index', 'join-order-pushdown', 'join-limit-pushdown'],
433
3255
  },
434
3256
  {
435
- name: 'run steps by run query',
436
- resource: 'runStep',
437
- purpose: 'one-to-many run-step lookup keeps type and run relation in SQL self-join',
438
- minScale: 'small',
3257
+ name: 'extreme native exact graph VALUES thread query',
3258
+ resource: 'message',
3259
+ purpose: 'high fanout exact-graph VALUES BGP checks native VALUES row scheduling',
3260
+ minScale: 'medium',
3261
+ minReturnedRows: 200,
439
3262
  query: {
440
3263
  patterns: [
441
3264
  {
442
- graph: { $startsWith: 'https://pod.example/alice/.data/task/default/2026/05/' },
443
- subject: { variable: 'step' },
444
- predicate: namedNode(RDF_TYPE),
445
- object: namedNode(`${UDFS}RunStep`),
3265
+ graph: namedNode(NATIVE_STRESS_GRAPH),
3266
+ subject: { variable: 'message' },
3267
+ predicate: namedNode(SIOC_HAS_MEMBER),
3268
+ object: { variable: 'thread' },
446
3269
  },
447
3270
  {
448
- graph: { $startsWith: 'https://pod.example/alice/.data/task/default/2026/05/' },
449
- subject: { variable: 'step' },
450
- predicate: namedNode(`${UDFS}run`),
451
- object: namedNode('https://pod.example/alice/.data/task/default/2026/05/18/runs.ttl#run_1'),
3271
+ graph: namedNode(NATIVE_STRESS_GRAPH),
3272
+ subject: { variable: 'message' },
3273
+ predicate: namedNode(DCT_CREATED),
3274
+ object: { variable: 'createdAt' },
452
3275
  },
453
3276
  ],
454
- select: ['step'],
455
- orderBy: [
3277
+ values: [
456
3278
  {
457
- variable: 'step',
458
- direction: 'asc',
3279
+ variables: ['thread'],
3280
+ rows: syntheticThreadValueRows(32),
459
3281
  },
460
3282
  ],
461
- limit: 50,
3283
+ select: ['message', 'thread', 'createdAt'],
3284
+ limit: 512,
462
3285
  },
463
- expectedPlan: ['join-index', 'join-order-pushdown', 'join-limit-pushdown'],
3286
+ expectedPlan: ['join-index', 'values-join-pushdown', 'join-limit-pushdown'],
464
3287
  },
465
3288
  {
466
- name: 'task materialization active due query',
467
- resource: 'schedule',
468
- purpose: 'task scheduler materialization keeps active status and due-time filter in SQL self-join',
469
- minScale: 'small',
3289
+ name: 'extreme native exact graph count distinct thread query',
3290
+ resource: 'message',
3291
+ purpose: 'high fanout exact-graph COUNT and COUNT DISTINCT checks native BGP count',
3292
+ minScale: 'medium',
3293
+ minReturnedRows: 1,
470
3294
  query: {
471
3295
  patterns: [
472
3296
  {
473
- graph: { $startsWith: 'https://pod.example/alice/.data/task/default/' },
474
- subject: { variable: 'schedule' },
3297
+ graph: namedNode(NATIVE_STRESS_GRAPH),
3298
+ subject: { variable: 'message' },
475
3299
  predicate: namedNode(RDF_TYPE),
476
- object: namedNode(`${UDFS}Schedule`),
477
- },
478
- {
479
- graph: { $startsWith: 'https://pod.example/alice/.data/task/default/' },
480
- subject: { variable: 'schedule' },
481
- predicate: namedNode(`${UDFS}status`),
482
- object: literal('active'),
3300
+ object: namedNode(`${MEETING}Message`),
483
3301
  },
484
3302
  {
485
- graph: { $startsWith: 'https://pod.example/alice/.data/task/default/' },
486
- subject: { variable: 'schedule' },
487
- predicate: namedNode(`${UDFS}nextRunAt`),
488
- object: { variable: 'nextRunAt' },
3303
+ graph: namedNode(NATIVE_STRESS_GRAPH),
3304
+ subject: { variable: 'message' },
3305
+ predicate: namedNode(SIOC_HAS_MEMBER),
3306
+ object: { variable: 'thread' },
489
3307
  },
490
3308
  ],
491
- filters: [
3309
+ aggregates: [
492
3310
  {
493
- variable: 'nextRunAt',
494
- operator: '$lte',
495
- value: literal('2026-05-18T01:30:00.000Z'),
3311
+ type: 'count',
3312
+ as: 'messageCount',
3313
+ variable: 'message',
496
3314
  },
497
- ],
498
- select: ['schedule', 'nextRunAt'],
499
- orderBy: [
500
3315
  {
501
- variable: 'nextRunAt',
502
- direction: 'asc',
3316
+ type: 'count',
3317
+ as: 'threadCount',
3318
+ variable: 'thread',
3319
+ distinct: true,
503
3320
  },
504
3321
  ],
505
- limit: 100,
3322
+ select: ['messageCount', 'threadCount'],
506
3323
  },
507
- expectedPlan: ['join-index', 'range-filter-pushdown', 'join-order-pushdown', 'join-limit-pushdown'],
3324
+ expectedPlan: ['join-count-index'],
508
3325
  },
509
3326
  {
510
- name: 'message count by thread with having',
3327
+ name: 'extreme native exact graph grouped count by thread query',
511
3328
  resource: 'message',
512
- purpose: 'grouped message count uses SQL GROUP BY/HAVING before pagination',
513
- minScale: 'small',
3329
+ purpose: 'high fanout exact-graph grouped count checks native BGP group-count summary',
3330
+ minScale: 'medium',
3331
+ minReturnedRows: 10,
514
3332
  query: {
515
3333
  patterns: [
516
3334
  {
517
- graph: { $startsWith: 'https://pod.example/alice/.data/chat/default/' },
3335
+ graph: namedNode(NATIVE_STRESS_GRAPH),
518
3336
  subject: { variable: 'message' },
519
3337
  predicate: namedNode(SIOC_HAS_MEMBER),
520
3338
  object: { variable: 'thread' },
521
3339
  },
522
3340
  ],
523
3341
  groupBy: ['thread'],
524
- aggregate: {
525
- type: 'count',
526
- as: 'count',
527
- variable: 'message',
528
- },
3342
+ aggregates: [
3343
+ {
3344
+ type: 'count',
3345
+ as: 'messageCount',
3346
+ variable: 'message',
3347
+ },
3348
+ ],
529
3349
  having: [
530
3350
  {
531
- variable: 'count',
3351
+ variable: 'messageCount',
532
3352
  operator: '$gt',
533
- value: literal('2', namedNode('http://www.w3.org/2001/XMLSchema#integer')),
3353
+ value: literal('8', namedNode(XSD_INTEGER)),
534
3354
  },
535
3355
  ],
536
- select: ['thread', 'count'],
3356
+ select: ['thread', 'messageCount'],
537
3357
  orderBy: [
538
3358
  {
539
- variable: 'count',
3359
+ variable: 'messageCount',
540
3360
  direction: 'desc',
541
3361
  },
3362
+ {
3363
+ variable: 'thread',
3364
+ direction: 'asc',
3365
+ },
542
3366
  ],
543
- limit: 1,
3367
+ limit: 10,
544
3368
  },
545
3369
  expectedPlan: ['group-count-index', 'having-pushdown', 'order', 'limit'],
546
3370
  },
547
3371
  {
548
- name: 'message score by thread numeric aggregate',
3372
+ name: 'extreme native exact graph grouped numeric aggregate by thread query',
549
3373
  resource: 'message',
550
- purpose: 'grouped numeric message score aggregate stays inside SQL/RDF-3X GROUP BY',
551
- minScale: 'small',
552
- minReturnedRows: 1,
3374
+ purpose: 'high fanout exact-graph grouped numeric summary checks native BGP numeric aggregate',
3375
+ minScale: 'medium',
3376
+ minReturnedRows: 10,
553
3377
  query: {
554
3378
  patterns: [
555
3379
  {
556
- graph: { $startsWith: 'https://pod.example/alice/.data/chat/default/' },
3380
+ graph: namedNode(NATIVE_STRESS_GRAPH),
557
3381
  subject: { variable: 'message' },
558
3382
  predicate: namedNode(SIOC_HAS_MEMBER),
559
3383
  object: { variable: 'thread' },
560
3384
  },
561
3385
  {
562
- graph: { $startsWith: 'https://pod.example/alice/.data/chat/default/' },
3386
+ graph: namedNode(NATIVE_STRESS_GRAPH),
563
3387
  subject: { variable: 'message' },
564
3388
  predicate: namedNode(`${UDFS}score`),
565
3389
  object: { variable: 'score' },
566
3390
  },
3391
+ {
3392
+ graph: namedNode(NATIVE_STRESS_GRAPH),
3393
+ subject: { variable: 'message' },
3394
+ predicate: namedNode(`${UDFS}status`),
3395
+ object: literal('indexed'),
3396
+ },
567
3397
  ],
568
3398
  filters: [
569
3399
  {
@@ -576,7 +3406,7 @@ exports.rdfModelsQueryBenchmarkCases = [
576
3406
  aggregates: [
577
3407
  {
578
3408
  type: 'count',
579
- as: 'count',
3409
+ as: 'messageCount',
580
3410
  variable: 'message',
581
3411
  },
582
3412
  {
@@ -589,68 +3419,104 @@ exports.rdfModelsQueryBenchmarkCases = [
589
3419
  as: 'scoreAvg',
590
3420
  variable: 'score',
591
3421
  },
3422
+ {
3423
+ type: 'max',
3424
+ as: 'scoreMax',
3425
+ variable: 'score',
3426
+ },
592
3427
  ],
593
3428
  having: [
594
3429
  {
595
3430
  variable: 'scoreTotal',
596
3431
  operator: '$gt',
597
- value: literal('4', namedNode('http://www.w3.org/2001/XMLSchema#integer')),
3432
+ value: literal('100', namedNode(XSD_INTEGER)),
598
3433
  },
599
3434
  ],
600
- select: ['thread', 'count', 'scoreTotal', 'scoreAvg'],
3435
+ select: ['thread', 'messageCount', 'scoreTotal', 'scoreAvg', 'scoreMax'],
601
3436
  orderBy: [
602
3437
  {
603
3438
  variable: 'scoreTotal',
604
3439
  direction: 'desc',
605
3440
  },
606
- ],
607
- limit: 1,
608
- },
609
- expectedPlan: ['group-aggregate-index', 'having-pushdown', 'order', 'limit'],
610
- },
611
- {
612
- name: 'message join count distinct',
613
- resource: 'message',
614
- purpose: 'message/thread BGP aggregate count stays inside SQL self-join',
615
- minScale: 'small',
616
- query: {
617
- patterns: [
618
- {
619
- graph: { $startsWith: 'https://pod.example/alice/.data/chat/default/' },
620
- subject: { variable: 'message' },
621
- predicate: namedNode(RDF_TYPE),
622
- object: namedNode(`${MEETING}Message`),
623
- },
624
- {
625
- graph: { $startsWith: 'https://pod.example/alice/.data/chat/default/' },
626
- subject: { variable: 'message' },
627
- predicate: namedNode(SIOC_HAS_MEMBER),
628
- object: { variable: 'thread' },
629
- },
630
- ],
631
- aggregates: [
632
- {
633
- type: 'count',
634
- as: 'messageCount',
635
- variable: 'message',
636
- },
637
3441
  {
638
- type: 'count',
639
- as: 'threadCount',
640
3442
  variable: 'thread',
641
- distinct: true,
3443
+ direction: 'asc',
642
3444
  },
643
3445
  ],
3446
+ limit: 10,
644
3447
  },
645
- expectedPlan: ['join-count-index'],
3448
+ expectedPlan: ['numeric-aggregate'],
646
3449
  },
647
3450
  ];
3451
+ function rdfModelsBenchmarkCasesForProfile(profile) {
3452
+ switch (profile) {
3453
+ case 'default':
3454
+ return exports.rdfModelsBenchmarkCases;
3455
+ case 'extreme':
3456
+ return exports.rdfModelsExtremeBenchmarkCases;
3457
+ case 'fusion':
3458
+ return [];
3459
+ case 'all':
3460
+ return [...exports.rdfModelsBenchmarkCases, ...exports.rdfModelsExtremeBenchmarkCases];
3461
+ default: {
3462
+ const exhaustive = profile;
3463
+ return exhaustive;
3464
+ }
3465
+ }
3466
+ }
3467
+ function rdfModelsQueryBenchmarkCasesForProfile(profile) {
3468
+ switch (profile) {
3469
+ case 'default':
3470
+ return exports.rdfModelsQueryBenchmarkCases;
3471
+ case 'extreme':
3472
+ return exports.rdfModelsExtremeQueryBenchmarkCases;
3473
+ case 'fusion':
3474
+ return exports.rdfModelsSearchFusionQueryBenchmarkCases;
3475
+ case 'all':
3476
+ return [...exports.rdfModelsQueryBenchmarkCases, ...exports.rdfModelsExtremeQueryBenchmarkCases, ...exports.rdfModelsSearchFusionQueryBenchmarkCases];
3477
+ default: {
3478
+ const exhaustive = profile;
3479
+ return exhaustive;
3480
+ }
3481
+ }
3482
+ }
3483
+ function rdfModelsPostgresQueryBenchmarkCasesForProfile(profile) {
3484
+ switch (profile) {
3485
+ case 'default':
3486
+ return exports.rdfModelsPostgresQueryBenchmarkCases;
3487
+ case 'extreme':
3488
+ return exports.rdfModelsExtremeQueryBenchmarkCases;
3489
+ case 'fusion':
3490
+ return exports.rdfModelsSearchFusionQueryBenchmarkCases;
3491
+ case 'all':
3492
+ return [...exports.rdfModelsPostgresQueryBenchmarkCases, ...exports.rdfModelsExtremeQueryBenchmarkCases, ...exports.rdfModelsSearchFusionQueryBenchmarkCases];
3493
+ default: {
3494
+ const exhaustive = profile;
3495
+ return exhaustive;
3496
+ }
3497
+ }
3498
+ }
648
3499
  function rdfModelsBenchmarkCaseNames() {
649
3500
  return exports.rdfModelsBenchmarkCases.map((testCase) => testCase.name);
650
3501
  }
651
3502
  function rdfModelsQueryBenchmarkCaseNames() {
652
3503
  return exports.rdfModelsQueryBenchmarkCases.map((testCase) => testCase.name);
653
3504
  }
3505
+ function rdfModelsPostgresQueryBenchmarkCaseNames() {
3506
+ return exports.rdfModelsPostgresQueryBenchmarkCases.map((testCase) => testCase.name);
3507
+ }
3508
+ function rdfModelsPostgresMaterializedQueryBenchmarkCaseNames() {
3509
+ return exports.rdfModelsPostgresMaterializedQueryBenchmarkCases.map((testCase) => testCase.name);
3510
+ }
3511
+ function rdfModelsSearchFusionQueryBenchmarkCaseNames() {
3512
+ return exports.rdfModelsSearchFusionQueryBenchmarkCases.map((testCase) => testCase.name);
3513
+ }
3514
+ function rdfModelsExtremeBenchmarkCaseNames() {
3515
+ return exports.rdfModelsExtremeBenchmarkCases.map((testCase) => testCase.name);
3516
+ }
3517
+ function rdfModelsExtremeQueryBenchmarkCaseNames() {
3518
+ return exports.rdfModelsExtremeQueryBenchmarkCases.map((testCase) => testCase.name);
3519
+ }
654
3520
  function rdfModelsBenchmarkScaleTargetQuads(scale) {
655
3521
  return RDF_MODELS_SCALE_TARGET_QUADS[scale];
656
3522
  }
@@ -660,44 +3526,979 @@ function rdfModelsBenchmarkSyntheticPodCount(scale) {
660
3526
  function estimateRdfModelsSyntheticQuadCount(syntheticMessages) {
661
3527
  return Math.max(0, Math.floor(syntheticMessages)) * exports.RDF_MODELS_SYNTHETIC_MESSAGE_QUADS;
662
3528
  }
3529
+ function syntheticMessagesForRdfModelsTargetQuads(targetQuads) {
3530
+ return Math.ceil(Math.max(0, Math.floor(targetQuads)) / exports.RDF_MODELS_SYNTHETIC_MESSAGE_QUADS);
3531
+ }
663
3532
  function defaultSyntheticMessagesForRdfModelsScale(scale) {
664
3533
  if (scale === 'small') {
665
3534
  return 12;
666
3535
  }
667
- return Math.ceil(rdfModelsBenchmarkScaleTargetQuads(scale) / exports.RDF_MODELS_SYNTHETIC_MESSAGE_QUADS);
3536
+ return syntheticMessagesForRdfModelsTargetQuads(rdfModelsBenchmarkScaleTargetQuads(scale));
668
3537
  }
669
3538
  function rdfModelsBenchmarkScaleSatisfied(scale, seedQuadCount) {
670
3539
  return seedQuadCount >= rdfModelsBenchmarkScaleTargetQuads(scale);
671
3540
  }
3541
+ function rdfModelsBenchmarkTargetSatisfied(targetQuads, seedQuadCount) {
3542
+ return seedQuadCount >= Math.max(0, Math.floor(targetQuads));
3543
+ }
3544
+ function buildRdfModelsBenchmarkSeed(options) {
3545
+ const quads = [];
3546
+ seedChatTaskThreadRunProviderQuads(quads);
3547
+ seedAgentContactFavoriteQuads(quads);
3548
+ seedProfileAccessControlIssueQuads(quads);
3549
+ seedSessionAuditAiRuntimeQuads(quads);
3550
+ seedSettingsQuads(quads);
3551
+ seedCanonicalMessages(quads);
3552
+ seedSyntheticThreads(quads, options.syntheticPodCount);
3553
+ const caseProfile = options.caseProfile ?? 'default';
3554
+ const searchFusionBroadSourceCount = rdfModelsBenchmarkProfileRequiresSearchFusion(caseProfile)
3555
+ ? Math.max(0, Math.floor(options.searchFusionBroadSourceCount ?? exports.RDF_MODELS_SEARCH_FUSION_BROAD_SOURCE_COUNT))
3556
+ : 0;
3557
+ const syntheticMessages = rdfModelsBenchmarkProfileRequiresSearchFusion(caseProfile)
3558
+ ? Math.max(options.syntheticMessages, searchFusionBroadSourceCount + 3)
3559
+ : options.syntheticMessages;
3560
+ seedSyntheticMessages(quads, syntheticMessages, options.syntheticPodCount);
3561
+ if (searchFusionBroadSourceCount > 0) {
3562
+ seedPrimaryPodSearchFusionMessages(quads, searchFusionBroadSourceCount + 3, options.syntheticPodCount);
3563
+ }
3564
+ if (options.caseProfile === 'extreme' || options.caseProfile === 'all') {
3565
+ seedNativeStressMessages(quads);
3566
+ }
3567
+ return quads;
3568
+ }
3569
+ function rdfModelsBenchmarkProfileRequiresSearchFusion(profile) {
3570
+ return profile === 'fusion' || profile === 'all';
3571
+ }
3572
+ function rdfModelsSearchFusionBroadSourceCountForScale(scale) {
3573
+ return RDF_MODELS_SEARCH_FUSION_BROAD_SOURCE_COUNTS[scale];
3574
+ }
3575
+ async function seedRdfModelsSearchFusionIndexes(engine, options = {}) {
3576
+ for (const source of rdfModelsSearchFusionSources(options.broadSourceCount)) {
3577
+ const sourceInput = {
3578
+ source: source.source,
3579
+ workspace: WORKSPACE,
3580
+ localPath: source.localPath,
3581
+ contentType: 'text/markdown',
3582
+ sourceVersion: '2026-05-18',
3583
+ };
3584
+ const chunk = {
3585
+ chunkKey: 'context',
3586
+ ordinal: 0,
3587
+ level: 1,
3588
+ heading: source.heading,
3589
+ path: [source.heading],
3590
+ content: source.content,
3591
+ startOffset: 0,
3592
+ endOffset: source.content.length,
3593
+ };
3594
+ await engine.indexTextSource(sourceInput, source.content, [chunk]);
3595
+ await engine.indexVectorSource(sourceInput, [{
3596
+ ...chunk,
3597
+ embedding: source.embedding,
3598
+ model: RDF_MODELS_SEARCH_VECTOR_MODEL,
3599
+ }]);
3600
+ }
3601
+ }
3602
+ function rdfModelsSearchFusionSources(broadSourceCount = exports.RDF_MODELS_SEARCH_FUSION_BROAD_SOURCE_COUNT) {
3603
+ const focusedSources = [
3604
+ {
3605
+ source: syntheticMessageIri(DATA, 0),
3606
+ localPath: '.data/chat/default/2026/05/01/messages.ttl#synthetic_0',
3607
+ heading: 'Runtime Approvals',
3608
+ content: 'Runtime approvals mention repository context and active agent steering.',
3609
+ embedding: [0.95, 0.2, 0.05],
3610
+ },
3611
+ {
3612
+ source: syntheticMessageIri(DATA, 1),
3613
+ localPath: '.data/chat/default/2026/05/02/messages.ttl#synthetic_1',
3614
+ heading: 'Runtime Follow Up',
3615
+ content: 'Runtime approvals follow-up with workspace notes and summary context.',
3616
+ embedding: [0.9, 0.25, 0.05],
3617
+ },
3618
+ {
3619
+ source: syntheticMessageIri(DATA, 2),
3620
+ localPath: '.data/chat/default/2026/05/03/messages.ttl#synthetic_2',
3621
+ heading: 'Irrelevant Note',
3622
+ content: 'Unrelated billing and profile note without the target wording.',
3623
+ embedding: [0.05, 0.1, 0.95],
3624
+ },
3625
+ ];
3626
+ const broadSources = Array.from({ length: Math.max(0, Math.floor(broadSourceCount)) }, (_, index) => {
3627
+ const sourceIndex = index + 3;
3628
+ const day = String((sourceIndex % 28) + 1).padStart(2, '0');
3629
+ return {
3630
+ source: syntheticMessageIri(DATA, sourceIndex),
3631
+ localPath: `.data/chat/default/2026/05/${day}/messages.ttl#synthetic_${sourceIndex}`,
3632
+ heading: `Candidate Retrieval ${index + 1}`,
3633
+ content: `Candidate retrieval context chunk ${index + 1} with workspace evidence and structured message links.`,
3634
+ embedding: [0.82, 0.48 - (index % 5) * 0.01, 0.12],
3635
+ };
3636
+ });
3637
+ return [...focusedSources, ...broadSources];
3638
+ }
3639
+ function seedChatTaskThreadRunProviderQuads(quads) {
3640
+ const chatGraph = `${DATA}/chat/default/index.ttl`;
3641
+ const chat = `${chatGraph}#this`;
3642
+ const thread = `${chatGraph}#thread_1`;
3643
+ const taskGraph = `${DATA}/task/index.ttl`;
3644
+ const task = `${taskGraph}#default`;
3645
+ const taskThreadGraph = `${DATA}/task/default/index.ttl`;
3646
+ const taskThread = `${taskThreadGraph}#thread_1`;
3647
+ const scheduleGraph = `${DATA}/task/default/2026/05/18/schedules.ttl`;
3648
+ const runGraph = `${DATA}/task/default/2026/05/18/runs.ttl`;
3649
+ const run = `${runGraph}#run_1`;
3650
+ const latestMessage = `${DATA}/chat/default/2026/05/18/messages.ttl#msg_3`;
3651
+ const provider = `${SETTINGS}/providers/anthropic.ttl`;
3652
+ const model = `${provider}#claude-sonnet-4`;
3653
+ const credentialGraph = `${SETTINGS}/credentials.ttl`;
3654
+ const credential = `${credentialGraph}#anthropic-default`;
3655
+ const standbyCredential = `${credentialGraph}#anthropic-standby`;
3656
+ const oauthCredential = `${credentialGraph}#github-oauth`;
3657
+ quads.push(seedQuad(chat, RDF_TYPE, iri(`${MEETING}LongChat`), chatGraph), seedQuad(chat, DCT_TITLE, literal('Default chat'), chatGraph), seedQuad(chat, DCT_MODIFIED, literal('2026-05-18T00:00:00.000Z'), chatGraph), seedQuad(chat, `${UDFS}favorite`, literal('true', iri(XSD_BOOLEAN)), chatGraph), seedQuad(chat, `${UDFS}lastActiveAt`, literal('2026-05-18T00:03:00.000Z'), chatGraph), seedQuad(chat, `${UDFS}lastMessage`, iri(latestMessage), chatGraph), seedQuad(thread, RDF_TYPE, iri(`${SIOC}Thread`), chatGraph), seedQuad(thread, SIOC_HAS_PARENT, iri(chat), chatGraph), seedQuad(thread, `${UDFS}status`, literal('active'), chatGraph), seedQuad(thread, DCT_CREATED, literal('2026-05-18T00:00:01.000Z'), chatGraph), seedQuad(thread, `${UDFS}workspace`, iri(WORKSPACE), chatGraph), seedQuad(task, RDF_TYPE, iri(`${UDFS}Task`), taskGraph), seedQuad(task, DCT_TITLE, literal('Daily repository summary'), taskGraph), seedQuad(task, `${UDFS}prompt`, literal('Summarize repository changes and open approvals.'), taskGraph), seedQuad(task, `${UDFS}status`, literal('active'), taskGraph), seedQuad(task, `${UDFS}workspace`, iri(WORKSPACE), taskGraph), seedQuad(task, `${UDFS}runner`, literal('pi'), taskGraph), seedQuad(task, `${UDFS}triggerKind`, literal('cron'), taskGraph), seedQuad(task, `${UDFS}cron`, literal('0 * * * *'), taskGraph), seedQuad(task, `${UDFS}nextRunAt`, literal('2026-05-18T01:00:00.000Z'), taskGraph), seedQuad(task, `${UDFS}lastRunAt`, literal('2026-05-18T00:00:00.000Z'), taskGraph), seedQuad(task, `${UDFS}inThread`, iri(taskThread), taskGraph), seedQuad(taskThread, RDF_TYPE, iri(`${SIOC}Thread`), taskThreadGraph), seedQuad(taskThread, `${UDFS}status`, literal('active'), taskThreadGraph), seedQuad(taskThread, DCT_CREATED, literal('2026-05-18T00:30:00.000Z'), taskThreadGraph), seedQuad(`${scheduleGraph}#schedule_1`, RDF_TYPE, iri(`${UDFS}Schedule`), scheduleGraph), seedQuad(`${scheduleGraph}#schedule_1`, `${UDFS}status`, literal('active'), scheduleGraph), seedQuad(`${scheduleGraph}#schedule_1`, `${UDFS}nextRunAt`, literal('2026-05-18T01:00:00.000Z'), scheduleGraph), seedQuad(run, RDF_TYPE, iri(`${UDFS}Run`), runGraph), seedQuad(run, `${UDFS}commandKind`, literal('task'), runGraph), seedQuad(run, `${UDFS}surfaceId`, literal('default'), runGraph), seedQuad(run, `${UDFS}task`, iri(task), runGraph), seedQuad(run, `${UDFS}inThread`, iri(taskThread), runGraph), seedQuad(run, `${UDFS}runner`, literal('pi'), runGraph), seedQuad(run, `${UDFS}prompt`, literal('Summarize repository changes and open approvals.'), runGraph), seedQuad(run, DCT_CREATED, literal('2026-05-18T01:00:00.000Z'), runGraph), seedQuad(run, `${UDFS}status`, literal('queued'), runGraph), seedQuad(run, `${UDFS}workspace`, iri(WORKSPACE), runGraph), seedQuad(run, `${UDFS}priority`, literal('10', iri(XSD_INTEGER)), runGraph), seedQuad(`${runGraph}#run_2`, RDF_TYPE, iri(`${UDFS}Run`), runGraph), seedQuad(`${runGraph}#run_2`, DCT_CREATED, literal('2026-05-18T01:05:00.000Z'), runGraph), seedQuad(`${runGraph}#run_2`, `${UDFS}status`, literal('queued'), runGraph), seedQuad(`${runGraph}#run_2`, `${UDFS}workspace`, iri(WORKSPACE), runGraph), seedQuad(`${runGraph}#run_2`, `${UDFS}priority`, literal('2', iri(XSD_INTEGER)), runGraph), seedQuad(`${runGraph}#run_3`, RDF_TYPE, iri(`${UDFS}Run`), runGraph), seedQuad(`${runGraph}#run_3`, DCT_CREATED, literal('2026-05-18T01:10:00.000Z'), runGraph), seedQuad(`${runGraph}#run_3`, `${UDFS}status`, literal('running'), runGraph), seedQuad(`${runGraph}#run_3`, `${UDFS}workspace`, iri(WORKSPACE), runGraph), seedQuad(`${runGraph}#run_3`, `${UDFS}priority`, literal('8', iri(XSD_INTEGER)), runGraph), seedQuad(`${runGraph}#run_3`, `${UDFS}leaseOwner`, literal('worker-1'), runGraph), seedQuad(`${runGraph}#run_3`, `${UDFS}leaseExpiresAt`, literal('2026-05-18T01:15:00.000Z'), runGraph), seedQuad(`${runGraph}#run_3`, `${UDFS}heartbeatAt`, literal('2026-05-18T01:11:00.000Z'), runGraph), seedQuad(`${runGraph}#run_4`, RDF_TYPE, iri(`${UDFS}Run`), runGraph), seedQuad(`${runGraph}#run_4`, DCT_CREATED, literal('2026-05-18T01:20:00.000Z'), runGraph), seedQuad(`${runGraph}#run_4`, `${UDFS}status`, literal('waiting_input'), runGraph), seedQuad(`${runGraph}#run_4`, `${UDFS}workspace`, iri(WORKSPACE), runGraph), seedQuad(`${runGraph}#run_4`, `${UDFS}runner`, literal('pi'), runGraph), seedQuad(`${runGraph}#step_1`, RDF_TYPE, iri(`${UDFS}RunStep`), runGraph), seedQuad(`${runGraph}#step_1`, `${UDFS}run`, iri(run), runGraph), seedQuad(`${runGraph}#step_1`, `${UDFS}status`, literal('runtime.tool_call'), runGraph), seedQuad(`${runGraph}#step_1`, DCT_CREATED, literal('2026-05-18T01:00:05.000Z'), runGraph), seedQuad(`${runGraph}#step_2`, RDF_TYPE, iri(`${UDFS}RunStep`), runGraph), seedQuad(`${runGraph}#step_2`, `${UDFS}run`, iri(run), runGraph), seedQuad(`${runGraph}#step_2`, `${UDFS}status`, literal('run.completed'), runGraph), seedQuad(`${runGraph}#step_2`, DCT_CREATED, literal('2026-05-18T01:00:10.000Z'), runGraph), seedQuad(provider, RDF_TYPE, iri(`${XPOD_AI}Provider`), provider), seedQuad(provider, `${XPOD_AI}displayName`, literal('Anthropic'), provider), seedQuad(provider, `${XPOD_AI}baseUrl`, literal('https://api.anthropic.com/v1'), provider), seedQuad(provider, `${XPOD_AI}hasModel`, iri(model), provider), seedQuad(provider, `${XPOD_AI}defaultModel`, iri(model), provider), seedQuad(model, RDF_TYPE, iri(`${XPOD_AI}Model`), provider), seedQuad(model, `${XPOD_AI}isProvidedBy`, iri(provider), provider), seedQuad(model, `${XPOD_AI}status`, literal('active'), provider), seedQuad(model, `${XPOD_AI}modelType`, literal('chat'), provider), seedQuad(model, `${XPOD_AI}dimension`, literal('0', iri(XSD_INTEGER)), provider), seedQuad(credential, RDF_TYPE, iri(`${XPOD_CREDENTIAL}Credential`), credentialGraph), seedQuad(credential, `${XPOD_CREDENTIAL}provider`, iri(provider), credentialGraph), seedQuad(credential, `${XPOD_CREDENTIAL}service`, literal('ai'), credentialGraph), seedQuad(credential, `${XPOD_CREDENTIAL}status`, literal('active'), credentialGraph), seedQuad(credential, `${XPOD_CREDENTIAL}apiKey`, literal('sk-ant-test'), credentialGraph), seedQuad(credential, `${XPOD_CREDENTIAL}isDefault`, literal('true', iri(XSD_BOOLEAN)), credentialGraph), seedQuad(credential, `${XPOD_CREDENTIAL}lastUsedAt`, literal('2026-05-18T00:00:00.000Z'), credentialGraph), seedQuad(credential, `${XPOD_CREDENTIAL}failCount`, literal('15', iri(XSD_INTEGER)), credentialGraph), seedQuad(standbyCredential, RDF_TYPE, iri(`${XPOD_CREDENTIAL}Credential`), credentialGraph), seedQuad(standbyCredential, `${XPOD_CREDENTIAL}provider`, iri(provider), credentialGraph), seedQuad(standbyCredential, `${XPOD_CREDENTIAL}service`, literal('ai'), credentialGraph), seedQuad(standbyCredential, `${XPOD_CREDENTIAL}status`, literal('active'), credentialGraph), seedQuad(standbyCredential, `${XPOD_CREDENTIAL}apiKey`, literal('sk-ant-standby'), credentialGraph), seedQuad(standbyCredential, `${XPOD_CREDENTIAL}isDefault`, literal('false', iri(XSD_BOOLEAN)), credentialGraph), seedQuad(standbyCredential, `${XPOD_CREDENTIAL}lastUsedAt`, literal('2026-05-17T00:00:00.000Z'), credentialGraph), seedQuad(standbyCredential, `${XPOD_CREDENTIAL}failCount`, literal('0', iri(XSD_INTEGER)), credentialGraph), seedQuad(oauthCredential, RDF_TYPE, iri(`${XPOD_CREDENTIAL}Credential`), credentialGraph), seedQuad(oauthCredential, `${XPOD_CREDENTIAL}service`, literal('github'), credentialGraph), seedQuad(oauthCredential, `${XPOD_CREDENTIAL}status`, literal('active'), credentialGraph), seedQuad(oauthCredential, `${XPOD_CREDENTIAL}label`, literal('GitHub OAuth'), credentialGraph), seedQuad(oauthCredential, `${XPOD_CREDENTIAL}oauthRefreshToken`, literal('gho-refresh-test'), credentialGraph), seedQuad(oauthCredential, `${XPOD_CREDENTIAL}oauthAccessToken`, literal('gho-access-test'), credentialGraph), seedQuad(oauthCredential, `${XPOD_CREDENTIAL}oauthExpiresAt`, literal('2026-05-18T23:00:00.000Z'), credentialGraph));
3658
+ }
3659
+ function seedSettingsQuads(quads) {
3660
+ const owner = `${exports.RDF_MODELS_BENCHMARK_POD}/profile/card#me`;
3661
+ const uiThemeGraph = `${SETTINGS}/ui.theme.ttl`;
3662
+ const aiDefaultAssistantGraph = `${SETTINGS}/ai.defaultAssistant.ttl`;
3663
+ const aiProviderSecretGraph = `${SETTINGS}/ai.providerSecret.ttl`;
3664
+ quads.push(seedQuad(uiThemeGraph, RDF_TYPE, iri(SCHEMA_PROPERTY_VALUE), uiThemeGraph), seedQuad(uiThemeGraph, `${UDFS}settingKey`, literal('ui.theme'), uiThemeGraph), seedQuad(uiThemeGraph, `${UDFS}settingValue`, literal('dark'), uiThemeGraph), seedQuad(uiThemeGraph, `${UDFS}settingType`, literal('string'), uiThemeGraph), seedQuad(uiThemeGraph, DCT_TYPE, literal('ui'), uiThemeGraph), seedQuad(uiThemeGraph, DCT_CREATOR, iri(owner), uiThemeGraph), seedQuad(uiThemeGraph, DCT_TITLE, literal('Theme'), uiThemeGraph), seedQuad(uiThemeGraph, DCT_CREATED, literal('2026-05-18T00:00:00.000Z'), uiThemeGraph), seedQuad(uiThemeGraph, DCT_MODIFIED, literal('2026-05-18T00:00:00.000Z'), uiThemeGraph), seedQuad(aiDefaultAssistantGraph, RDF_TYPE, iri(SCHEMA_PROPERTY_VALUE), aiDefaultAssistantGraph), seedQuad(aiDefaultAssistantGraph, `${UDFS}settingKey`, literal('ai.defaultAssistant'), aiDefaultAssistantGraph), seedQuad(aiDefaultAssistantGraph, `${UDFS}settingValue`, literal(`${DATA}/agents/secretary.ttl#this`), aiDefaultAssistantGraph), seedQuad(aiDefaultAssistantGraph, `${UDFS}settingType`, literal('uri'), aiDefaultAssistantGraph), seedQuad(aiDefaultAssistantGraph, DCT_TYPE, literal('ai'), aiDefaultAssistantGraph), seedQuad(aiDefaultAssistantGraph, DCT_CREATOR, iri(owner), aiDefaultAssistantGraph), seedQuad(aiDefaultAssistantGraph, DCT_DESCRIPTION, literal('Default AI assistant for chat and task commands.'), aiDefaultAssistantGraph), seedQuad(aiProviderSecretGraph, RDF_TYPE, iri(SCHEMA_PROPERTY_VALUE), aiProviderSecretGraph), seedQuad(aiProviderSecretGraph, `${UDFS}settingKey`, literal('ai.providerSecret'), aiProviderSecretGraph), seedQuad(aiProviderSecretGraph, `${UDFS}settingValue`, literal('encrypted:test'), aiProviderSecretGraph), seedQuad(aiProviderSecretGraph, `${UDFS}settingType`, literal('string'), aiProviderSecretGraph), seedQuad(aiProviderSecretGraph, DCT_TYPE, literal('ai'), aiProviderSecretGraph), seedQuad(aiProviderSecretGraph, DCT_CREATOR, iri(owner), aiProviderSecretGraph), seedQuad(aiProviderSecretGraph, `${UDFS}status`, literal('true', iri(XSD_BOOLEAN)), aiProviderSecretGraph));
3665
+ }
3666
+ function seedAgentContactFavoriteQuads(quads) {
3667
+ const agentGraph = `${DATA}/agents/secretary.ttl`;
3668
+ const agent = `${agentGraph}#this`;
3669
+ const contactGraph = `${DATA}/contacts/secretary.ttl`;
3670
+ const contact = contactGraph;
3671
+ const favoriteGraph = `${DATA}/favorites/2026/05/18.ttl`;
3672
+ const favorite = `${favoriteGraph}#favorite_1`;
3673
+ const chat = `${DATA}/chat/default/index.ttl#this`;
3674
+ quads.push(seedQuad(agent, RDF_TYPE, iri(FOAF_AGENT), agentGraph), seedQuad(agent, `${UDFS}provider`, literal('anthropic'), agentGraph), seedQuad(agent, `${UDFS}model`, literal('claude-sonnet-4'), agentGraph), seedQuad(contact, RDF_TYPE, iri(VCARD_INDIVIDUAL), contactGraph), seedQuad(contact, FOAF_PRIMARY_TOPIC, iri(agent), contactGraph), seedQuad(contact, `${UDFS}contactType`, literal('agent'), contactGraph), seedQuad(contact, `${UDFS}favorite`, literal('true'), contactGraph), seedQuad(favorite, RDF_TYPE, iri(SCHEMA_CREATIVE_WORK), favoriteGraph), seedQuad(favorite, `${UDFS}favoriteTarget`, iri(chat), favoriteGraph), seedQuad(favorite, `${UDFS}favoredAt`, literal('2026-05-18T02:00:00.000Z'), favoriteGraph));
3675
+ }
3676
+ function seedProfileAccessControlIssueQuads(quads) {
3677
+ const profileGraph = `${exports.RDF_MODELS_BENCHMARK_POD}/profile/card`;
3678
+ const profile = `${profileGraph}#me`;
3679
+ const profileAclGraph = `${profileGraph}.acl`;
3680
+ const profileAclAuthorization = `${profileAclGraph}#public`;
3681
+ const profileAcrGraph = `${exports.RDF_MODELS_BENCHMARK_POD}/profile/.acr`;
3682
+ const profileAccessControl = `${profileAcrGraph}#publicReadAccess`;
3683
+ const issueGraph = `${DATA}/issues/issue_1.ttl`;
3684
+ const issue = issueGraph;
3685
+ const approvalGraph = `${DATA}/approvals/2026/05/18.ttl`;
3686
+ const approval = `${approvalGraph}#approval_1`;
3687
+ const grantGraph = `${SETTINGS}/autonomy/grants/default.ttl`;
3688
+ const grant = grantGraph;
3689
+ const inboxGraph = `${exports.RDF_MODELS_BENCHMARK_POD}/inbox/notification_1.ttl`;
3690
+ const inboxNotification = inboxGraph;
3691
+ quads.push(seedQuad(profile, RDF_TYPE, iri(FOAF_PERSON), profileGraph), seedQuad(profile, VCARD_FN, literal('Alice'), profileGraph), seedQuad(profile, LDP_INBOX, iri(`${exports.RDF_MODELS_BENCHMARK_POD}/inbox/`), profileGraph), seedQuad(profileAclAuthorization, RDF_TYPE, iri(`${ACL}Authorization`), profileAclGraph), seedQuad(profileAclAuthorization, `${ACL}accessTo`, iri(profileGraph), profileAclGraph), seedQuad(profileAclAuthorization, `${ACL}mode`, iri(`${ACL}Read`), profileAclGraph), seedQuad(profileGraph, `${ACP}accessControl`, iri(profileAccessControl), profileAcrGraph), seedQuad(profileAccessControl, `${ACP}apply`, iri(profileGraph), profileAcrGraph), seedQuad(profileAccessControl, `${ACP}allow`, iri(`${ACP}Read`), profileAcrGraph), seedQuad(issue, RDF_TYPE, iri(`${UDFS}Issue`), issueGraph), seedQuad(issue, DCT_TITLE, literal('Profile access regression'), issueGraph), seedQuad(issue, `${UDFS}status`, literal('open'), issueGraph), seedQuad(issue, `${UDFS}assignedTo`, iri(profile), issueGraph), seedQuad(approval, RDF_TYPE, iri(`${UDFS}ApprovalRequest`), approvalGraph), seedQuad(approval, `${UDFS}status`, literal('pending'), approvalGraph), seedQuad(approval, `${UDFS}assignedTo`, iri(profile), approvalGraph), seedQuad(approval, `${ODRL}target`, iri(WORKSPACE), approvalGraph), seedQuad(approval, `${ODRL}action`, iri(`${UDFS}runTool`), approvalGraph), seedQuad(grant, RDF_TYPE, iri(`${ODRL}Policy`), grantGraph), seedQuad(grant, RDF_TYPE, iri(`${UDFS}AutonomyGrant`), grantGraph), seedQuad(grant, `${ODRL}target`, iri(WORKSPACE), grantGraph), seedQuad(grant, `${ODRL}action`, iri(`${UDFS}runTool`), grantGraph), seedQuad(grant, `${UDFS}effect`, literal('allow'), grantGraph), seedQuad(inboxNotification, RDF_TYPE, iri(`${AS}Activity`), inboxGraph), seedQuad(inboxNotification, `${AS}actor`, iri(profile), inboxGraph), seedQuad(inboxNotification, `${AS}object`, iri(issue), inboxGraph), seedQuad(inboxNotification, DCT_CREATED, literal('2026-05-18T02:30:00.000Z'), inboxGraph));
3692
+ }
3693
+ function seedSessionAuditAiRuntimeQuads(quads) {
3694
+ const profile = `${exports.RDF_MODELS_BENCHMARK_POD}/profile/card#me`;
3695
+ const chatGraph = `${DATA}/chat/default/index.ttl`;
3696
+ const chat = `${chatGraph}#this`;
3697
+ const thread = `${chatGraph}#thread_1`;
3698
+ const message = `${DATA}/chat/default/2026/05/18/messages.ttl#msg_1`;
3699
+ const sessionGraph = `${DATA}/sessions/2026/05/18/session_1.ttl`;
3700
+ const session = sessionGraph;
3701
+ const approval = `${DATA}/approvals/2026/05/18.ttl#approval_1`;
3702
+ const grant = `${SETTINGS}/autonomy/grants/default.ttl`;
3703
+ const auditGraph = `${DATA}/audits/2026/05/18.ttl`;
3704
+ const audit = `${auditGraph}#audit_1`;
3705
+ const provider = `${SETTINGS}/providers/anthropic.ttl`;
3706
+ const model = `${provider}#claude-sonnet-4`;
3707
+ const aiConfigGraph = `${SETTINGS}/ai/config.ttl`;
3708
+ const aiConfig = `${aiConfigGraph}#default`;
3709
+ const vectorStoreGraph = `${SETTINGS}/ai/vector-stores.ttl`;
3710
+ const vectorStore = `${vectorStoreGraph}#chat-default`;
3711
+ const indexedFileGraph = `${SETTINGS}/ai/indexed-files.ttl`;
3712
+ const indexedFile = `${indexedFileGraph}#chat-default-messages`;
3713
+ const agentStatusGraph = `${SETTINGS}/ai/agent-status.ttl`;
3714
+ const agentStatus = `${agentStatusGraph}#secretary`;
3715
+ quads.push(seedQuad(session, RDF_TYPE, iri(`${UDFS}Session`), sessionGraph), seedQuad(session, `${UDFS}actor`, iri(profile), sessionGraph), seedQuad(session, `${UDFS}conversation`, iri(chat), sessionGraph), seedQuad(session, `${UDFS}inThread`, iri(thread), sessionGraph), seedQuad(session, `${UDFS}conversationType`, literal('direct'), sessionGraph), seedQuad(session, `${UDFS}sessionStatus`, literal('active'), sessionGraph), seedQuad(session, `${UDFS}sessionTool`, literal('codex'), sessionGraph), seedQuad(session, `${UDFS}tokenUsage`, literal('1500', iri(XSD_INTEGER)), sessionGraph), seedQuad(session, `${UDFS}messageResource`, iri(message), sessionGraph), seedQuad(session, `${UDFS}policy`, iri(grant), sessionGraph), seedQuad(session, `${UDFS}policyVersion`, literal('2026-05'), sessionGraph), seedQuad(session, DCT_CREATED, literal('2026-05-18T03:00:00.000Z'), sessionGraph), seedQuad(session, DCT_MODIFIED, literal('2026-05-18T03:10:00.000Z'), sessionGraph), seedQuad(audit, RDF_TYPE, iri(`${UDFS}AuditEntry`), auditGraph), seedQuad(audit, `${UDFS}action`, literal('runTool'), auditGraph), seedQuad(audit, `${UDFS}actor`, iri(profile), auditGraph), seedQuad(audit, `${UDFS}actorRole`, literal('owner'), auditGraph), seedQuad(audit, `${UDFS}onBehalfOf`, iri(profile), auditGraph), seedQuad(audit, `${UDFS}session`, iri(session), auditGraph), seedQuad(audit, `${UDFS}conversation`, iri(chat), auditGraph), seedQuad(audit, `${UDFS}inThread`, iri(thread), auditGraph), seedQuad(audit, `${UDFS}entry`, iri(`${DATA}/task/default/2026/05/18/runs.ttl#step_1`), auditGraph), seedQuad(audit, `${UDFS}toolCallId`, literal('call_1'), auditGraph), seedQuad(audit, `${UDFS}toolName`, literal('bash'), auditGraph), seedQuad(audit, `${UDFS}approval`, iri(approval), auditGraph), seedQuad(audit, `${UDFS}policy`, iri(grant), auditGraph), seedQuad(audit, `${UDFS}policyVersion`, literal('v1'), auditGraph), seedQuad(audit, DCT_CREATED, literal('2026-05-18T03:05:00.000Z'), auditGraph), seedQuad(aiConfig, RDF_TYPE, iri(`${XPOD_AI}AIConfig`), aiConfigGraph), seedQuad(aiConfig, `${XPOD_AI}embeddingModel`, iri(model), aiConfigGraph), seedQuad(aiConfig, `${XPOD_AI}previousModel`, iri(model), aiConfigGraph), seedQuad(aiConfig, `${XPOD_AI}migrationStatus`, literal('ready'), aiConfigGraph), seedQuad(aiConfig, `${XPOD_AI}migrationProgress`, literal('100', iri(XSD_INTEGER)), aiConfigGraph), seedQuad(aiConfig, `${XPOD_AI}updatedAt`, literal('2026-05-18T03:15:00.000Z'), aiConfigGraph), seedQuad(vectorStore, RDF_TYPE, iri(`${XPOD_AI}VectorStore`), vectorStoreGraph), seedQuad(vectorStore, `${XPOD_AI}name`, literal('Default chat vectors'), vectorStoreGraph), seedQuad(vectorStore, `${XPOD_AI}container`, iri(`${DATA}/chat/default/`), vectorStoreGraph), seedQuad(vectorStore, `${XPOD_AI}chunkingStrategy`, literal('markdown-heading-v1'), vectorStoreGraph), seedQuad(vectorStore, `${XPOD_AI}status`, literal('active'), vectorStoreGraph), seedQuad(vectorStore, `${XPOD_AI}createdAt`, literal('2026-05-18T03:20:00.000Z'), vectorStoreGraph), seedQuad(vectorStore, `${XPOD_AI}lastActiveAt`, literal('2026-05-18T03:25:00.000Z'), vectorStoreGraph), seedQuad(indexedFile, RDF_TYPE, iri(`${XPOD_AI}IndexedFile`), indexedFileGraph), seedQuad(indexedFile, `${XPOD_AI}fileUrl`, iri(`${DATA}/chat/default/2026/05/18/messages.ttl`), indexedFileGraph), seedQuad(indexedFile, `${XPOD_AI}vectorId`, literal('42', iri(XSD_INTEGER)), indexedFileGraph), seedQuad(indexedFile, `${XPOD_AI}chunkingStrategy`, literal('markdown-heading-v1'), indexedFileGraph), seedQuad(indexedFile, `${XPOD_AI}status`, literal('indexed'), indexedFileGraph), seedQuad(indexedFile, `${XPOD_AI}usageBytes`, literal('2048', iri(XSD_INTEGER)), indexedFileGraph), seedQuad(indexedFile, `${XPOD_AI}indexedAt`, literal('2026-05-18T03:30:00.000Z'), indexedFileGraph), seedQuad(agentStatus, RDF_TYPE, iri(`${XPOD_AI}AgentStatus`), agentStatusGraph), seedQuad(agentStatus, `${XPOD_AI}agentId`, literal('secretary'), agentStatusGraph), seedQuad(agentStatus, `${XPOD_AI}status`, literal('running'), agentStatusGraph), seedQuad(agentStatus, `${XPOD_AI}startedAt`, literal('2026-05-18T03:35:00.000Z'), agentStatusGraph), seedQuad(agentStatus, `${XPOD_AI}lastActivityAt`, literal('2026-05-18T03:40:00.000Z'), agentStatusGraph), seedQuad(agentStatus, `${XPOD_AI}currentTaskId`, literal('default'), agentStatusGraph));
3716
+ }
3717
+ function seedCanonicalMessages(quads) {
3718
+ const chat = `${DATA}/chat/default/index.ttl#this`;
3719
+ const thread = `${DATA}/chat/default/index.ttl#thread_1`;
3720
+ const graph = `${DATA}/chat/default/2026/05/18/messages.ttl`;
3721
+ const scores = ['2', '10', '4'];
3722
+ const profile = `${exports.RDF_MODELS_BENCHMARK_POD}/profile/card#me`;
3723
+ const agent = `${DATA}/agents/secretary.ttl#this`;
3724
+ for (let index = 0; index < 3; index += 1) {
3725
+ const message = `${graph}#msg_${index + 1}`;
3726
+ const timestamp = `2026-05-18T00:0${index + 1}:00.000Z`;
3727
+ const maker = index === 0 ? profile : agent;
3728
+ quads.push(seedQuad(message, RDF_TYPE, iri(`${MEETING}Message`), graph), seedQuad(message, SIOC_HAS_MEMBER, iri(thread), graph), seedQuad(message, SIOC_HAS_CONTAINER, iri(thread), graph), seedQuad(chat, WF_MESSAGE, iri(message), graph), seedQuad(message, FOAF_MAKER, iri(maker), graph), seedQuad(message, `${UDFS}messageType`, literal(index === 0 ? 'user' : 'assistant'), graph), seedQuad(message, `${UDFS}messageStatus`, literal('completed'), graph), seedQuad(message, DCT_CREATED, literal(timestamp), graph), seedQuad(message, DCT_MODIFIED, literal(timestamp), graph), seedQuad(message, `${UDFS}score`, literal(scores[index], namedNode(XSD_INTEGER)), graph), seedQuad(message, SIOC_CONTENT, literal(`canonical message ${index + 1}`), graph));
3729
+ }
3730
+ quads.push(seedQuad(`${graph}#msg_2`, `${UDFS}replyTo`, iri(`${graph}#msg_1`), graph), seedQuad(`${graph}#msg_3`, `${UDFS}routeTargetAgentId`, literal('secretary'), graph), seedQuad(`${graph}#msg_3`, `${UDFS}coordinationId`, literal('coordination_1'), graph));
3731
+ }
3732
+ function seedSyntheticThreads(quads, podCount) {
3733
+ const syntheticPodCount = Math.max(1, Math.floor(podCount));
3734
+ for (let podIndex = 0; podIndex < syntheticPodCount; podIndex += 1) {
3735
+ const pod = podIndex === 0 ? exports.RDF_MODELS_BENCHMARK_POD : `https://pod.example/synthetic-${podIndex}`;
3736
+ const data = `${pod}/.data`;
3737
+ const graph = `${data}/chat/default/index.ttl`;
3738
+ for (let threadIndex = 0; threadIndex < RDF_MODELS_SYNTHETIC_THREAD_COUNT; threadIndex += 1) {
3739
+ const thread = syntheticThreadIri(data, threadIndex);
3740
+ const createdAt = new Date(Date.UTC(2026, 4, 1, 0, threadIndex, podIndex)).toISOString();
3741
+ quads.push(seedQuad(thread, RDF_TYPE, iri(`${SIOC}Thread`), graph), seedQuad(thread, `${UDFS}workspace`, iri(WORKSPACE), graph), seedQuad(thread, DCT_CREATED, literal(createdAt), graph));
3742
+ }
3743
+ }
3744
+ }
3745
+ function seedSyntheticMessages(quads, count, podCount) {
3746
+ const syntheticPodCount = Math.max(1, Math.floor(podCount));
3747
+ for (let index = 0; index < count; index += 1) {
3748
+ const podIndex = index % syntheticPodCount;
3749
+ const pod = podIndex === 0 ? exports.RDF_MODELS_BENCHMARK_POD : `https://pod.example/synthetic-${podIndex}`;
3750
+ const data = `${pod}/.data`;
3751
+ seedSyntheticMessage(quads, data, index);
3752
+ }
3753
+ }
3754
+ function seedPrimaryPodSearchFusionMessages(quads, count, podCount) {
3755
+ const syntheticPodCount = Math.max(1, Math.floor(podCount));
3756
+ if (syntheticPodCount === 1) {
3757
+ return;
3758
+ }
3759
+ for (let index = 0; index < count; index += 1) {
3760
+ if (index % syntheticPodCount === 0) {
3761
+ continue;
3762
+ }
3763
+ seedSyntheticMessage(quads, DATA, index);
3764
+ }
3765
+ }
3766
+ function seedSyntheticMessage(quads, data, index) {
3767
+ const thread = syntheticThreadIri(data, index % RDF_MODELS_SYNTHETIC_THREAD_COUNT);
3768
+ const dayNumber = (index % 28) + 1;
3769
+ const day = String(dayNumber).padStart(2, '0');
3770
+ const graph = `${data}/chat/default/2026/05/${day}/messages.ttl`;
3771
+ const message = syntheticMessageIri(data, index);
3772
+ const timestamp = new Date(Date.UTC(2026, 4, dayNumber, 12, 0, index)).toISOString();
3773
+ const score = String((index % 100) + 1);
3774
+ const rank = String(index + 1);
3775
+ quads.push(seedQuad(message, RDF_TYPE, iri(`${MEETING}Message`), graph), seedQuad(message, SIOC_HAS_MEMBER, iri(thread), graph), seedQuad(message, DCT_CREATED, literal(timestamp), graph), seedQuad(message, DCT_MODIFIED, literal(timestamp), graph), seedQuad(message, SIOC_CONTENT, literal(`synthetic searchable message ${index}`), graph), seedQuad(message, `${UDFS}score`, literal(score, iri(XSD_INTEGER)), graph), seedQuad(message, `${UDFS}rank`, literal(rank, iri(XSD_INTEGER)), graph), seedQuad(message, `${UDFS}status`, literal('indexed'), graph), seedQuad(message, `${UDFS}workspace`, iri(WORKSPACE), graph));
3776
+ }
3777
+ function seedNativeStressMessages(quads) {
3778
+ for (let index = 0; index < exports.RDF_MODELS_NATIVE_STRESS_MESSAGE_COUNT; index += 1) {
3779
+ const thread = syntheticThreadIri(DATA, index % RDF_MODELS_SYNTHETIC_THREAD_COUNT);
3780
+ const message = `${NATIVE_STRESS_GRAPH}#native_${index}`;
3781
+ const timestamp = new Date(Date.UTC(2026, 4, 18, 13, 0, index)).toISOString();
3782
+ const score = String((index % 100) + 1);
3783
+ const rank = String(index + 1);
3784
+ quads.push(seedQuad(message, RDF_TYPE, iri(`${MEETING}Message`), NATIVE_STRESS_GRAPH), seedQuad(message, SIOC_HAS_MEMBER, iri(thread), NATIVE_STRESS_GRAPH), seedQuad(message, DCT_CREATED, literal(timestamp), NATIVE_STRESS_GRAPH), seedQuad(message, DCT_MODIFIED, literal(timestamp), NATIVE_STRESS_GRAPH), seedQuad(message, SIOC_CONTENT, literal(`native stress searchable message ${index}`), NATIVE_STRESS_GRAPH), seedQuad(message, `${UDFS}score`, literal(score, iri(XSD_INTEGER)), NATIVE_STRESS_GRAPH), seedQuad(message, `${UDFS}rank`, literal(rank, iri(XSD_INTEGER)), NATIVE_STRESS_GRAPH), seedQuad(message, `${UDFS}status`, literal('indexed'), NATIVE_STRESS_GRAPH), seedQuad(message, `${UDFS}workspace`, iri(WORKSPACE), NATIVE_STRESS_GRAPH));
3785
+ }
3786
+ }
3787
+ function syntheticThreadIri(data, threadIndex) {
3788
+ return `${data}/chat/default/index.ttl#thread_${threadIndex + 1}`;
3789
+ }
3790
+ function syntheticMessageIri(data, messageIndex) {
3791
+ const day = String((messageIndex % 28) + 1).padStart(2, '0');
3792
+ return `${data}/chat/default/2026/05/${day}/messages.ttl#synthetic_${messageIndex}`;
3793
+ }
3794
+ function syntheticThreadValueRows(count) {
3795
+ const rows = [];
3796
+ const safeCount = Math.min(Math.max(0, Math.floor(count)), RDF_MODELS_SYNTHETIC_THREAD_COUNT);
3797
+ for (let index = 0; index < safeCount; index += 1) {
3798
+ rows.push({
3799
+ thread: namedNode(syntheticThreadIri(DATA, index)),
3800
+ });
3801
+ }
3802
+ return rows;
3803
+ }
3804
+ function seedQuad(subject, predicate, object, graph) {
3805
+ return quad(namedNode(subject), namedNode(predicate), object, namedNode(graph));
3806
+ }
3807
+ function iri(value) {
3808
+ return namedNode(value);
3809
+ }
672
3810
  function runRdfModelsBenchmark(engine, options = {}) {
673
3811
  const scale = options.scale ?? 'small';
674
3812
  const iterations = Math.max(1, Math.floor(options.iterations ?? 1));
675
- const cases = (options.cases ?? exports.rdfModelsBenchmarkCases)
3813
+ const caseProfile = options.caseProfile ?? 'default';
3814
+ const cases = (options.cases ?? rdfModelsBenchmarkCasesForProfile(caseProfile))
3815
+ .filter((testCase) => scaleRank(testCase.minScale) <= scaleRank(scale));
3816
+ const queryCases = (options.queryCases ?? rdfModelsQueryBenchmarkCasesForProfile(caseProfile))
3817
+ .filter((testCase) => scaleRank(testCase.minScale) <= scaleRank(scale));
3818
+ const results = cases.map((testCase) => runBenchmarkCase(engine, testCase, iterations));
3819
+ const queryResults = queryCases.map((testCase) => runQueryBenchmarkCase(engine, testCase, iterations));
3820
+ const failedPlanCases = [
3821
+ ...results.filter((result) => !result.planMatched).map((result) => result.name),
3822
+ ...queryResults.filter((result) => !result.planMatched).map((result) => result.name),
3823
+ ];
3824
+ const storage = engine.storageStats();
3825
+ return {
3826
+ engine: 'solid-rdf',
3827
+ scale,
3828
+ caseProfile,
3829
+ iterations,
3830
+ generatedAt: new Date().toISOString(),
3831
+ planMatched: failedPlanCases.length === 0,
3832
+ failedPlanCases,
3833
+ performanceCosts: benchmarkPerformanceCosts(storage),
3834
+ storage,
3835
+ cases: results,
3836
+ queryCases: queryResults,
3837
+ };
3838
+ }
3839
+ async function runRdfModelsPostgresBenchmark(engine, options = {}) {
3840
+ const scale = options.scale ?? 'small';
3841
+ const iterations = Math.max(1, Math.floor(options.iterations ?? 1));
3842
+ const warmupIterations = Math.max(0, Math.floor(options.warmupIterations ?? 1));
3843
+ const concurrency = Math.max(1, Math.floor(options.concurrency ?? 1));
3844
+ const caseProfile = options.caseProfile ?? 'default';
3845
+ const refreshMutationSources = Math.max(0, Math.floor(options.refreshMutationSources ?? 0));
3846
+ const refreshMutationQuadsPerSource = Math.max(1, Math.floor(options.refreshMutationQuadsPerSource ?? 6));
3847
+ if (refreshMutationSources > 0 && options.refreshDerivedIndexes === false) {
3848
+ throw new Error('refreshMutationSources requires the initial refreshDerivedIndexes pass');
3849
+ }
3850
+ let refresh;
3851
+ let refreshBenchmark;
3852
+ let postWriteRefreshBenchmark;
3853
+ if (options.refreshDerivedIndexes !== false) {
3854
+ const refreshStartedAt = Date.now();
3855
+ refresh = await engine.refreshDerivedIndexes();
3856
+ refreshBenchmark = postgresRefreshBenchmark(refresh, Date.now() - refreshStartedAt);
3857
+ }
3858
+ if (refreshMutationSources > 0) {
3859
+ postWriteRefreshBenchmark = await runPostWriteRefreshBenchmark(engine, refreshMutationSources, refreshMutationQuadsPerSource);
3860
+ }
3861
+ const storageBefore = await engine.storageStats();
3862
+ const cases = (options.cases ?? rdfModelsBenchmarkCasesForProfile(caseProfile))
676
3863
  .filter((testCase) => scaleRank(testCase.minScale) <= scaleRank(scale));
677
- const queryCases = (options.queryCases ?? exports.rdfModelsQueryBenchmarkCases)
3864
+ const queryCases = (options.queryCases ?? rdfModelsPostgresQueryBenchmarkCasesForProfile(caseProfile))
678
3865
  .filter((testCase) => scaleRank(testCase.minScale) <= scaleRank(scale));
679
- const results = cases.map((testCase) => runBenchmarkCase(engine, testCase, iterations));
680
- const queryResults = queryCases.map((testCase) => runQueryBenchmarkCase(engine, testCase, iterations));
3866
+ const firstQueryAfterRefresh = refresh
3867
+ ? await runPostgresColdStartFirstQuery(engine, queryCases)
3868
+ : undefined;
3869
+ const results = [];
3870
+ for (const testCase of cases) {
3871
+ results.push(await runAsyncBenchmarkCase(engine, testCase, iterations, storageBefore.facts, warmupIterations));
3872
+ }
3873
+ const queryResults = [];
3874
+ for (const testCase of queryCases) {
3875
+ queryResults.push(await runAsyncQueryBenchmarkCase(engine, testCase, iterations, storageBefore.facts, warmupIterations));
3876
+ }
3877
+ const concurrencyGate = await runPostgresConcurrencyGate(engine, queryCases, queryResults, concurrency, storageBefore.facts);
3878
+ const servingRegressionGate = runPostgresServingRegressionGate(caseProfile, queryResults, options.servingRegressionThresholds);
3879
+ const fusionBenchmarkGate = runPostgresFusionBenchmarkGate(caseProfile, queryResults, options.fusionBenchmarkThresholds, options.fusionBenchmarkBaselines);
3880
+ const coldStartBenchmark = postgresColdStartBenchmark(storageBefore, firstQueryAfterRefresh, queryResults, warmupIterations);
681
3881
  const failedPlanCases = [
682
3882
  ...results.filter((result) => !result.planMatched).map((result) => result.name),
683
3883
  ...queryResults.filter((result) => !result.planMatched).map((result) => result.name),
3884
+ ...concurrencyGate.failedCases.map((caseName) => `concurrency:${caseName}`),
3885
+ ...servingRegressionGate.failedCases.map((caseName) => `serving-regression:${caseName}`),
3886
+ ...fusionBenchmarkGate.failedCases.map((caseName) => `fusion:${caseName}`),
684
3887
  ];
3888
+ const storage = await engine.storageStats();
3889
+ const performanceCosts = benchmarkPerformanceCosts(storage, refreshBenchmark, coldStartBenchmark);
685
3890
  return {
686
- engine: 'solid-rdf',
3891
+ engine: 'postgres-rdf',
687
3892
  scale,
3893
+ caseProfile,
688
3894
  iterations,
3895
+ warmupIterations,
3896
+ concurrency,
689
3897
  generatedAt: new Date().toISOString(),
690
3898
  planMatched: failedPlanCases.length === 0,
691
3899
  failedPlanCases,
692
- storage: engine.storageStats(),
3900
+ concurrencyGate,
3901
+ servingRegressionGate,
3902
+ fusionBenchmarkGate,
3903
+ ...(refresh ? { refresh } : {}),
3904
+ ...(refreshBenchmark ? { refreshBenchmark } : {}),
3905
+ ...(postWriteRefreshBenchmark ? { postWriteRefreshBenchmark } : {}),
3906
+ ...(coldStartBenchmark ? { coldStartBenchmark } : {}),
3907
+ performanceCosts,
3908
+ storage,
693
3909
  cases: results,
694
3910
  queryCases: queryResults,
695
3911
  };
696
3912
  }
3913
+ function benchmarkPerformanceCosts(storage, refreshBenchmark, coldStartBenchmark) {
3914
+ return {
3915
+ storageOverhead: {
3916
+ factsBytes: storage.factsBytes,
3917
+ derivedBytes: storage.derivedBytes,
3918
+ totalBytes: storage.totalBytes,
3919
+ derivedToFactsRatio: storage.derivedToFactsRatio,
3920
+ totalToFactsRatio: storage.totalToFactsRatio,
3921
+ },
3922
+ ...(refreshBenchmark ? {
3923
+ indexBuild: {
3924
+ durationMs: refreshBenchmark.durationMs,
3925
+ refreshed: refreshBenchmark.refreshed,
3926
+ ...(refreshBenchmark.plannerStatsDurationMs !== undefined ? { plannerStatsDurationMs: refreshBenchmark.plannerStatsDurationMs } : {}),
3927
+ ...(refreshBenchmark.rebuildMode ? { rebuildMode: refreshBenchmark.rebuildMode } : {}),
3928
+ ...(refreshBenchmark.dirtyGraphs !== undefined ? { dirtyGraphs: refreshBenchmark.dirtyGraphs } : {}),
3929
+ ...(refreshBenchmark.dirtyPairs !== undefined ? { dirtyPairs: refreshBenchmark.dirtyPairs } : {}),
3930
+ ...(refreshBenchmark.dirtyTerms !== undefined ? { dirtyTerms: refreshBenchmark.dirtyTerms } : {}),
3931
+ },
3932
+ } : {}),
3933
+ ...(coldStartBenchmark?.startup ? {
3934
+ coldStart: {
3935
+ ...(coldStartBenchmark.startup.durationMs !== undefined ? { durationMs: coldStartBenchmark.startup.durationMs } : {}),
3936
+ },
3937
+ } : {}),
3938
+ };
3939
+ }
3940
+ async function runPostgresColdStartFirstQuery(engine, queryCases) {
3941
+ const testCase = selectPostgresColdStartQueryCase(queryCases);
3942
+ if (!testCase) {
3943
+ return undefined;
3944
+ }
3945
+ const query = {
3946
+ ...testCase.query,
3947
+ cache: {
3948
+ ...(testCase.query.cache ?? {}),
3949
+ mode: 'bypass',
3950
+ },
3951
+ };
3952
+ const startedAt = Date.now();
3953
+ const result = await engine.query(query);
3954
+ const durationMs = Math.max(0, Date.now() - startedAt);
3955
+ const keys = result.bindings.map(bindingKey);
3956
+ const missingPlan = missingExpectedQueryPlan(testCase, result.metrics, keys.length);
3957
+ return {
3958
+ queryCase: testCase.name,
3959
+ durationMs,
3960
+ planMatched: missingPlan.length === 0,
3961
+ missingPlan,
3962
+ physicalPlan: result.metrics.plan,
3963
+ indexChoices: result.metrics.indexChoices,
3964
+ scannedRows: result.metrics.scannedRows,
3965
+ returnedRows: keys.length,
3966
+ cacheMode: 'bypass',
3967
+ };
3968
+ }
3969
+ function selectPostgresColdStartQueryCase(queryCases) {
3970
+ return queryCases.find((testCase) => testCase.benchmarkCache !== 'preserve') ?? queryCases[0];
3971
+ }
3972
+ function postgresColdStartBenchmark(storageBefore, firstQueryAfterRefresh, queryResults, warmupIterations) {
3973
+ const lifecycle = storageBefore.lifecycle;
3974
+ const startup = lifecycle
3975
+ ? {
3976
+ status: lifecycle.status,
3977
+ ...(lifecycle.driver ? { driver: lifecycle.driver } : {}),
3978
+ openCount: lifecycle.openCount,
3979
+ ...(lifecycle.coldStart?.startedAt ? { startedAt: lifecycle.coldStart.startedAt } : {}),
3980
+ ...(lifecycle.coldStart?.readyAt ? { readyAt: lifecycle.coldStart.readyAt } : {}),
3981
+ ...(lifecycle.coldStart?.durationMs !== undefined ? { durationMs: lifecycle.coldStart.durationMs } : {}),
3982
+ phases: lifecycle.coldStart?.phases ?? [],
3983
+ }
3984
+ : undefined;
3985
+ const warmResult = firstQueryAfterRefresh
3986
+ ? queryResults.find((result) => result.name === firstQueryAfterRefresh.queryCase)
3987
+ : undefined;
3988
+ const warmSteadyState = warmResult
3989
+ ? {
3990
+ queryCase: warmResult.name,
3991
+ iterations: warmResult.durationsMs.length,
3992
+ warmupIterations,
3993
+ durationsMs: warmResult.durationsMs,
3994
+ p50DurationMs: warmResult.p50DurationMs,
3995
+ p95DurationMs: warmResult.p95DurationMs,
3996
+ planMatched: warmResult.planMatched,
3997
+ returnedRows: warmResult.returnedRows,
3998
+ }
3999
+ : undefined;
4000
+ if (!startup && !firstQueryAfterRefresh && !warmSteadyState) {
4001
+ return undefined;
4002
+ }
4003
+ return {
4004
+ ...(startup ? { startup } : {}),
4005
+ ...(firstQueryAfterRefresh ? { firstQueryAfterRefresh } : {}),
4006
+ ...(warmSteadyState ? { warmSteadyState } : {}),
4007
+ };
4008
+ }
4009
+ function postgresRefreshBenchmark(refresh, durationMs) {
4010
+ const rdf3x = refresh.rdf3x;
4011
+ return {
4012
+ durationMs,
4013
+ refreshed: rdf3x?.refreshed ?? false,
4014
+ previousFactsDataVersion: rdf3x?.previousFactsDataVersion,
4015
+ factsDataVersion: rdf3x?.factsDataVersion ?? refresh.factsDataVersion,
4016
+ syncedWithFacts: rdf3x?.syncedWithFacts,
4017
+ rebuildMode: rdf3x?.rebuild?.mode,
4018
+ dirtyGraphs: rdf3x?.rebuild && 'dirtyGraphs' in rdf3x.rebuild ? rdf3x.rebuild.dirtyGraphs : undefined,
4019
+ dirtyPairs: rdf3x?.rebuild && 'dirtyPairs' in rdf3x.rebuild ? rdf3x.rebuild.dirtyPairs : undefined,
4020
+ dirtyTerms: rdf3x?.rebuild && 'dirtyTerms' in rdf3x.rebuild ? rdf3x.rebuild.dirtyTerms : undefined,
4021
+ plannerStatsDurationMs: rdf3x?.plannerStats?.durationMs,
4022
+ analyzedTables: rdf3x?.plannerStats?.analyzedTables,
4023
+ sourceQueue: rdf3x?.sourceQueue,
4024
+ };
4025
+ }
4026
+ async function runPostWriteRefreshBenchmark(engine, mutationSources, mutationQuadsPerSource) {
4027
+ let mutationQuads = 0;
4028
+ for (let index = 0; index < mutationSources; index += 1) {
4029
+ const mutation = rdfModelsRefreshMutationSource(index, mutationQuadsPerSource);
4030
+ mutationQuads += mutation.quads.length;
4031
+ await engine.replaceSource(mutation.quads, mutation.source);
4032
+ }
4033
+ const storageBeforeRefresh = await engine.storageStats();
4034
+ const refreshStartedAt = Date.now();
4035
+ const refresh = await engine.refreshDerivedIndexes();
4036
+ const benchmark = {
4037
+ ...postgresRefreshBenchmark(refresh, Date.now() - refreshStartedAt),
4038
+ mutationSources,
4039
+ mutationQuadsPerSource,
4040
+ mutationQuads,
4041
+ pendingSourcesBeforeRefresh: storageBeforeRefresh.rdf3x?.pendingSources ?? 0,
4042
+ factsDataVersionBeforeRefresh: storageBeforeRefresh.rdf3x?.factsDataVersion,
4043
+ };
4044
+ const failedReasons = postWriteRefreshFailedReasons(benchmark);
4045
+ return {
4046
+ ...benchmark,
4047
+ matched: failedReasons.length === 0,
4048
+ failedReasons,
4049
+ };
4050
+ }
4051
+ function postWriteRefreshFailedReasons(benchmark) {
4052
+ const failedReasons = [];
4053
+ if (benchmark.pendingSourcesBeforeRefresh !== benchmark.mutationSources) {
4054
+ failedReasons.push('pending-sources-before-refresh-mismatch');
4055
+ }
4056
+ if (benchmark.sourceQueue?.pendingSources !== benchmark.mutationSources) {
4057
+ failedReasons.push('source-queue-pending-mismatch');
4058
+ }
4059
+ if (benchmark.sourceQueue?.drainedSources !== benchmark.mutationSources) {
4060
+ failedReasons.push('source-queue-drained-mismatch');
4061
+ }
4062
+ if (benchmark.refreshed !== true) {
4063
+ failedReasons.push('not-refreshed');
4064
+ }
4065
+ if (benchmark.syncedWithFacts !== true) {
4066
+ failedReasons.push('not-synced-with-facts');
4067
+ }
4068
+ if (benchmark.rebuildMode !== 'incremental') {
4069
+ failedReasons.push('not-incremental-rebuild');
4070
+ }
4071
+ if (benchmark.factsDataVersionBeforeRefresh === undefined) {
4072
+ failedReasons.push('missing-facts-data-version-before-refresh');
4073
+ }
4074
+ if (benchmark.factsDataVersion !== benchmark.factsDataVersionBeforeRefresh) {
4075
+ failedReasons.push('facts-data-version-mismatch');
4076
+ }
4077
+ return failedReasons;
4078
+ }
4079
+ function rdfModelsRefreshMutationSource(index, quadsPerSource) {
4080
+ const ordinal = index + 1;
4081
+ const graph = `${DATA}/task/default/2026/05/19/refresh-mutation-${ordinal}.ttl`;
4082
+ const run = `${graph}#run_${ordinal}`;
4083
+ const step = `${graph}#step_${ordinal}`;
4084
+ const thread = `${DATA}/task/default/index.ttl#thread_1`;
4085
+ const allQuads = [
4086
+ seedQuad(run, RDF_TYPE, iri(`${UDFS}Run`), graph),
4087
+ seedQuad(run, `${UDFS}status`, literal(index % 2 === 0 ? 'queued' : 'running'), graph),
4088
+ seedQuad(run, `${UDFS}workspace`, iri(WORKSPACE), graph),
4089
+ seedQuad(run, `${UDFS}priority`, literal(String((index % 20) + 1), iri(XSD_INTEGER)), graph),
4090
+ seedQuad(run, `${UDFS}inThread`, iri(thread), graph),
4091
+ seedQuad(run, DCT_CREATED, literal(new Date(Date.UTC(2026, 4, 19, 0, 0, index)).toISOString()), graph),
4092
+ seedQuad(step, RDF_TYPE, iri(`${UDFS}RunStep`), graph),
4093
+ seedQuad(step, `${UDFS}run`, iri(run), graph),
4094
+ seedQuad(step, `${UDFS}status`, literal('run.refresh_mutation'), graph),
4095
+ seedQuad(step, DCT_CREATED, literal(new Date(Date.UTC(2026, 4, 19, 0, 1, index)).toISOString()), graph),
4096
+ ];
4097
+ const quads = allQuads.slice(0, Math.max(1, Math.min(allQuads.length, Math.floor(quadsPerSource))));
4098
+ return {
4099
+ quads,
4100
+ source: {
4101
+ source: graph,
4102
+ workspace: exports.RDF_MODELS_BENCHMARK_POD,
4103
+ localPath: `/.data/task/default/2026/05/19/refresh-mutation-${ordinal}.ttl`,
4104
+ contentType: 'text/turtle',
4105
+ sourceVersion: `refresh-mutation-${ordinal}`,
4106
+ },
4107
+ };
4108
+ }
4109
+ async function runPostgresConcurrencyGate(engine, queryCases, baselineResults, concurrency, indexStats) {
4110
+ if (concurrency <= 1) {
4111
+ return {
4112
+ enabled: false,
4113
+ concurrency,
4114
+ cases: [],
4115
+ matched: true,
4116
+ failedCases: [],
4117
+ };
4118
+ }
4119
+ const baselineByName = new Map(baselineResults.map((result) => [result.name, result]));
4120
+ const selectedCases = selectPostgresConcurrencyGateCases(queryCases, baselineByName);
4121
+ const cases = [];
4122
+ for (const testCase of selectedCases) {
4123
+ const baseline = baselineByName.get(testCase.name);
4124
+ if (!baseline) {
4125
+ cases.push({
4126
+ name: testCase.name,
4127
+ concurrency,
4128
+ iterationsPerLane: 1,
4129
+ matched: false,
4130
+ planMatched: false,
4131
+ expectedReturnedRows: 0,
4132
+ returnedRows: [],
4133
+ expectedChecksum: '',
4134
+ checksums: [],
4135
+ expectedOrderedChecksum: '',
4136
+ orderedChecksums: [],
4137
+ missingPlan: ['missing serial benchmark baseline'],
4138
+ durationsMs: [],
4139
+ p50DurationMs: 0,
4140
+ p95DurationMs: 0,
4141
+ });
4142
+ continue;
4143
+ }
4144
+ const laneResults = await Promise.all(Array.from({ length: concurrency }, () => (runAsyncQueryBenchmarkCase(engine, testCase, 1, indexStats, 0))));
4145
+ const returnedRows = laneResults.map((result) => result.returnedRows);
4146
+ const checksums = laneResults.map((result) => result.checksum);
4147
+ const orderedChecksums = laneResults.map((result) => result.orderedChecksum);
4148
+ const durationsMs = laneResults.flatMap((result) => result.durationsMs);
4149
+ const missingPlan = [...new Set(laneResults.flatMap((result) => result.missingPlan))];
4150
+ const planMatched = laneResults.every((result) => result.planMatched);
4151
+ const matched = planMatched
4152
+ && returnedRows.every((rowCount) => rowCount === baseline.returnedRows)
4153
+ && checksums.every((value) => value === baseline.checksum)
4154
+ && orderedChecksums.every((value) => value === baseline.orderedChecksum);
4155
+ cases.push({
4156
+ name: testCase.name,
4157
+ concurrency,
4158
+ iterationsPerLane: 1,
4159
+ matched,
4160
+ planMatched,
4161
+ expectedReturnedRows: baseline.returnedRows,
4162
+ returnedRows,
4163
+ expectedChecksum: baseline.checksum,
4164
+ checksums,
4165
+ expectedOrderedChecksum: baseline.orderedChecksum,
4166
+ orderedChecksums,
4167
+ missingPlan,
4168
+ durationsMs,
4169
+ p50DurationMs: percentile(durationsMs, 0.5),
4170
+ p95DurationMs: percentile(durationsMs, 0.95),
4171
+ });
4172
+ }
4173
+ const failedCases = cases.filter((result) => !result.matched).map((result) => result.name);
4174
+ return {
4175
+ enabled: true,
4176
+ concurrency,
4177
+ cases,
4178
+ matched: failedCases.length === 0,
4179
+ failedCases,
4180
+ };
4181
+ }
4182
+ function postgresServingBenchmarkResultsForGate(caseProfile, queryResults) {
4183
+ if (caseProfile === 'default') {
4184
+ return queryResults;
4185
+ }
4186
+ if (caseProfile !== 'all') {
4187
+ return undefined;
4188
+ }
4189
+ const servingCaseNames = new Set(rdfModelsPostgresQueryBenchmarkCasesForProfile('default').map((testCase) => testCase.name));
4190
+ return queryResults.filter((result) => servingCaseNames.has(result.name));
4191
+ }
4192
+ function postgresFusionBenchmarkResultsForGate(caseProfile, queryResults) {
4193
+ if (caseProfile === 'fusion') {
4194
+ return queryResults;
4195
+ }
4196
+ if (caseProfile !== 'all') {
4197
+ return undefined;
4198
+ }
4199
+ const fusionCaseNames = new Set(rdfModelsSearchFusionQueryBenchmarkCaseNames());
4200
+ return queryResults.filter((result) => fusionCaseNames.has(result.name));
4201
+ }
4202
+ function runPostgresServingRegressionGate(caseProfile, queryResults, thresholds) {
4203
+ const gateResults = postgresServingBenchmarkResultsForGate(caseProfile, queryResults);
4204
+ if (!gateResults) {
4205
+ return {
4206
+ enabled: false,
4207
+ caseProfile,
4208
+ ...(thresholds ? { thresholds } : {}),
4209
+ cases: [],
4210
+ matched: true,
4211
+ failedCases: [],
4212
+ };
4213
+ }
4214
+ const cases = gateResults.map((result) => postgresServingRegressionGateCase(result, thresholds));
4215
+ const failedCases = cases.filter((result) => !result.matched).map((result) => result.name);
4216
+ return {
4217
+ enabled: true,
4218
+ caseProfile,
4219
+ ...(thresholds ? { thresholds } : {}),
4220
+ cases,
4221
+ matched: failedCases.length === 0,
4222
+ failedCases,
4223
+ };
4224
+ }
4225
+ function postgresServingRegressionGateCase(result, thresholds) {
4226
+ const failedReasons = postgresServingRegressionFailures(result, benchmarkGateThresholdsForCase(thresholds, result.name));
4227
+ return {
4228
+ name: result.name,
4229
+ matched: failedReasons.length === 0,
4230
+ planMatched: result.planMatched,
4231
+ expectedPlan: [...result.expectedPlan],
4232
+ missingPlan: [...result.missingPlan],
4233
+ failedReasons,
4234
+ physicalPlan: [...result.physicalPlan],
4235
+ scannedRows: result.scannedRows,
4236
+ returnedRows: result.returnedRows,
4237
+ p95DurationMs: result.p95DurationMs,
4238
+ };
4239
+ }
4240
+ function postgresServingRegressionFailures(result, thresholds) {
4241
+ const resolvedThresholds = benchmarkGateThresholdsForCase(thresholds, result.name);
4242
+ const failedReasons = [...result.missingPlan];
4243
+ const planText = result.physicalPlan.join('\n');
4244
+ const numericAggregate = result.expectedPlan.includes('numeric-aggregate')
4245
+ || result.expectedPlan.includes('numeric-aggregate-facts-cutover');
4246
+ const allowedFactsCutover = numericAggregate
4247
+ && planText.includes('PostgresNumericAggregateFactsCutover(');
4248
+ if (!result.planMatched) {
4249
+ failedReasons.push('plan-mismatch');
4250
+ }
4251
+ if (!allowedFactsCutover && planText.includes('PostgresFactsQuery')) {
4252
+ failedReasons.push('facts-query-fallback');
4253
+ }
4254
+ if (!allowedFactsCutover
4255
+ && !planText.includes('PostgresRdf3x')
4256
+ && !planText.includes('PostgresMaterializedResultHit')
4257
+ && !planText.includes('PostgresRdfNativeCustomIndex')) {
4258
+ failedReasons.push('missing-rdf3x-serving-path');
4259
+ }
4260
+ if (resolvedThresholds?.maxScannedRows !== undefined && result.scannedRows > resolvedThresholds.maxScannedRows) {
4261
+ failedReasons.push('scanned-rows-threshold');
4262
+ }
4263
+ if (resolvedThresholds?.maxP95DurationMs !== undefined
4264
+ && result.p95DurationMs > resolvedThresholds.maxP95DurationMs
4265
+ && !servingP95RegressionCoveredByOutlierBudget(result, resolvedThresholds)) {
4266
+ failedReasons.push('p95-duration-threshold');
4267
+ }
4268
+ return [...new Set(failedReasons)];
4269
+ }
4270
+ function servingP95RegressionCoveredByOutlierBudget(result, thresholds) {
4271
+ if (thresholds.maxP95DurationMs === undefined || thresholds.maxDurationMs === undefined) {
4272
+ return false;
4273
+ }
4274
+ if (!result.planMatched || result.missingPlan.length > 0) {
4275
+ return false;
4276
+ }
4277
+ if (thresholds.maxScannedRows !== undefined && result.scannedRows > thresholds.maxScannedRows) {
4278
+ return false;
4279
+ }
4280
+ if (result.p50DurationMs > thresholds.maxP95DurationMs) {
4281
+ return false;
4282
+ }
4283
+ return maxBenchmarkDurationMs(result) <= thresholds.maxDurationMs;
4284
+ }
4285
+ function maxBenchmarkDurationMs(result) {
4286
+ return Math.max(result.p95DurationMs, ...result.durationsMs);
4287
+ }
4288
+ function runPostgresFusionBenchmarkGate(caseProfile, queryResults, thresholds, baselines) {
4289
+ const gateResults = postgresFusionBenchmarkResultsForGate(caseProfile, queryResults);
4290
+ if (!gateResults) {
4291
+ return {
4292
+ enabled: false,
4293
+ caseProfile,
4294
+ ...(thresholds ? { thresholds } : {}),
4295
+ cases: [],
4296
+ matched: true,
4297
+ failedCases: [],
4298
+ };
4299
+ }
4300
+ const cases = gateResults.map((result) => postgresFusionBenchmarkGateCase(result, thresholds, baselines?.[result.name]));
4301
+ const failedCases = cases.filter((result) => !result.matched).map((result) => result.name);
4302
+ return {
4303
+ enabled: true,
4304
+ caseProfile,
4305
+ ...(thresholds ? { thresholds } : {}),
4306
+ cases,
4307
+ matched: failedCases.length === 0,
4308
+ failedCases,
4309
+ };
4310
+ }
4311
+ const POSTGRES_FUSION_BATCH_GATE_MIN_CANDIDATE_ROWS = 33;
4312
+ function postgresFusionBenchmarkGateCase(result, thresholds, baseline) {
4313
+ const planText = result.physicalPlan.join('\n');
4314
+ const candidateSources = postgresFusionCandidateSources(planText);
4315
+ const sourceEstimateCount = result.physicalPlan
4316
+ .filter((entry) => entry.startsWith('SourceEstimate('))
4317
+ .length;
4318
+ const sourceChoiceCount = result.physicalPlan
4319
+ .filter((entry) => entry.startsWith('PostgresPlannerSourceChoice('))
4320
+ .length;
4321
+ const hardFiltersBeforeRank = planText.includes('FusionHardFiltersBeforeRank(path,acl,output:?fusionScore)');
4322
+ const rankInputs = planText.includes('FusionRankInputs(text:?textScore,vector:?vectorScore,output:?fusionScore)');
4323
+ const rankWeights = planText.includes('FusionRankWeights(text:0.55,vector:0.45,output:?fusionScore)');
4324
+ const rankTieBreaker = planText.includes('FusionRankTieBreaker(asc:?message)');
4325
+ const resultCacheBypassed = !planText.includes('PostgresResultCache');
4326
+ const broadCandidateRows = postgresFusionBroadCandidateRows(result.physicalPlan);
4327
+ const batchedBroadCandidateJoin = postgresFusionBatchedBroadCandidateJoin(planText);
4328
+ const baselineComparison = baseline
4329
+ ? postgresBenchmarkBaselineComparison(result, baseline)
4330
+ : undefined;
4331
+ const failedReasons = postgresFusionBenchmarkFailures({
4332
+ result,
4333
+ candidateSources,
4334
+ sourceEstimateCount,
4335
+ sourceChoiceCount,
4336
+ hardFiltersBeforeRank,
4337
+ rankInputs,
4338
+ rankWeights,
4339
+ rankTieBreaker,
4340
+ resultCacheBypassed,
4341
+ broadCandidateRows,
4342
+ batchedBroadCandidateJoin,
4343
+ thresholds: benchmarkGateThresholdsForCase(thresholds, result.name),
4344
+ baselineComparison,
4345
+ });
4346
+ return {
4347
+ name: result.name,
4348
+ matched: failedReasons.length === 0,
4349
+ planMatched: result.planMatched,
4350
+ failedReasons,
4351
+ ...(baselineComparison ? { baselineComparison } : {}),
4352
+ candidateSources,
4353
+ sourceEstimateCount,
4354
+ sourceChoiceCount,
4355
+ hardFiltersBeforeRank,
4356
+ rankInputs,
4357
+ rankWeights,
4358
+ rankTieBreaker,
4359
+ resultCacheBypassed,
4360
+ broadCandidateRows,
4361
+ batchedBroadCandidateJoin,
4362
+ scannedRows: result.scannedRows,
4363
+ returnedRows: result.returnedRows,
4364
+ p95DurationMs: result.p95DurationMs,
4365
+ };
4366
+ }
4367
+ function postgresFusionCandidateSources(planText) {
4368
+ const sources = [
4369
+ 'TextMatchSource',
4370
+ 'VectorMatchSource',
4371
+ 'RdfBgpSource',
4372
+ 'PathScopeSource',
4373
+ 'AclScopeSource',
4374
+ ];
4375
+ return sources.filter((source) => (planText.includes(`${source}(`)
4376
+ || planText.includes(`SourceEstimate(${source}#`)));
4377
+ }
4378
+ function postgresFusionBroadCandidateRows(physicalPlan) {
4379
+ return Math.max(0, ...physicalPlan
4380
+ .map((entry) => {
4381
+ const match = /^SourceEstimate\((?:TextMatchSource|VectorMatchSource)#\d+ rows:(\d+)\b/.exec(entry);
4382
+ return match ? Number(match[1]) : 0;
4383
+ })
4384
+ .filter((value) => Number.isFinite(value)));
4385
+ }
4386
+ function postgresFusionBatchedBroadCandidateJoin(planText) {
4387
+ return planText.includes('PostgresFactsBatchScan(')
4388
+ && planText.includes('PostgresFactsSearchBatchSource(');
4389
+ }
4390
+ function postgresFusionBenchmarkFailures(input) {
4391
+ const requiredSources = [
4392
+ 'TextMatchSource',
4393
+ 'VectorMatchSource',
4394
+ 'RdfBgpSource',
4395
+ 'PathScopeSource',
4396
+ 'AclScopeSource',
4397
+ ];
4398
+ const failedReasons = [...input.result.missingPlan];
4399
+ if (!input.result.planMatched) {
4400
+ failedReasons.push('plan-mismatch');
4401
+ }
4402
+ for (const source of requiredSources) {
4403
+ if (!input.candidateSources.includes(source)) {
4404
+ failedReasons.push(`missing-source:${source}`);
4405
+ }
4406
+ }
4407
+ if (input.sourceEstimateCount < requiredSources.length) {
4408
+ failedReasons.push('missing-source-estimates');
4409
+ }
4410
+ if (input.sourceChoiceCount < 3) {
4411
+ failedReasons.push('missing-source-choice-evidence');
4412
+ }
4413
+ if (!input.hardFiltersBeforeRank) {
4414
+ failedReasons.push('missing-hard-filters-before-rank');
4415
+ }
4416
+ if (!input.rankInputs) {
4417
+ failedReasons.push('missing-rank-inputs');
4418
+ }
4419
+ if (!input.rankWeights) {
4420
+ failedReasons.push('missing-rank-weights');
4421
+ }
4422
+ if (!input.rankTieBreaker) {
4423
+ failedReasons.push('missing-rank-tie-breaker');
4424
+ }
4425
+ if (!input.resultCacheBypassed) {
4426
+ failedReasons.push('result-cache-enabled');
4427
+ }
4428
+ if (input.broadCandidateRows >= POSTGRES_FUSION_BATCH_GATE_MIN_CANDIDATE_ROWS
4429
+ && !input.batchedBroadCandidateJoin) {
4430
+ failedReasons.push('missing-batched-broad-candidate-join');
4431
+ }
4432
+ if (input.thresholds?.maxScannedRows !== undefined && input.result.scannedRows > input.thresholds.maxScannedRows) {
4433
+ failedReasons.push('scanned-rows-threshold');
4434
+ }
4435
+ if (input.thresholds?.maxP95DurationMs !== undefined && input.result.p95DurationMs > input.thresholds.maxP95DurationMs) {
4436
+ failedReasons.push('p95-duration-threshold');
4437
+ }
4438
+ if (input.baselineComparison && !input.baselineComparison.matched) {
4439
+ failedReasons.push(...input.baselineComparison.failedReasons);
4440
+ }
4441
+ return [...new Set(failedReasons)];
4442
+ }
4443
+ function benchmarkGateThresholdsForCase(thresholds, caseName) {
4444
+ if (!thresholds) {
4445
+ return undefined;
4446
+ }
4447
+ const caseThresholds = thresholds.cases?.[caseName];
4448
+ if (!caseThresholds) {
4449
+ return thresholds;
4450
+ }
4451
+ return {
4452
+ maxScannedRows: caseThresholds.maxScannedRows ?? thresholds.maxScannedRows,
4453
+ maxP95DurationMs: caseThresholds.maxP95DurationMs ?? thresholds.maxP95DurationMs,
4454
+ maxDurationMs: caseThresholds.maxDurationMs ?? thresholds.maxDurationMs,
4455
+ };
4456
+ }
4457
+ function postgresBenchmarkBaselineComparison(result, baseline) {
4458
+ const failedReasons = [];
4459
+ const comparison = {
4460
+ ...(baseline.label ? { label: baseline.label } : {}),
4461
+ matched: true,
4462
+ failedReasons,
4463
+ };
4464
+ if (baseline.p95DurationMs !== undefined) {
4465
+ comparison.p95DurationMsBaseline = baseline.p95DurationMs;
4466
+ comparison.maxP95DurationMs = baseline.maxP95DurationMs ?? baseline.p95DurationMs;
4467
+ comparison.p95DurationMsDelta = result.p95DurationMs - baseline.p95DurationMs;
4468
+ comparison.p95DurationMsRatio = ratio(result.p95DurationMs, baseline.p95DurationMs);
4469
+ if (result.p95DurationMs > comparison.maxP95DurationMs) {
4470
+ failedReasons.push('baseline-p95-regression');
4471
+ }
4472
+ }
4473
+ if (baseline.scannedRows !== undefined) {
4474
+ comparison.scannedRowsBaseline = baseline.scannedRows;
4475
+ comparison.maxScannedRows = baseline.maxScannedRows ?? baseline.scannedRows;
4476
+ comparison.scannedRowsDelta = result.scannedRows - baseline.scannedRows;
4477
+ comparison.scannedRowsRatio = ratio(result.scannedRows, baseline.scannedRows);
4478
+ if (result.scannedRows > comparison.maxScannedRows) {
4479
+ failedReasons.push('baseline-scanned-rows-regression');
4480
+ }
4481
+ }
4482
+ comparison.matched = failedReasons.length === 0;
4483
+ return comparison;
4484
+ }
4485
+ function selectPostgresConcurrencyGateCases(queryCases, baselineByName) {
4486
+ const preferred = POSTGRES_CONCURRENCY_GATE_QUERY_CASE_NAMES
4487
+ .map((name) => queryCases.find((testCase) => testCase.name === name))
4488
+ .filter((testCase) => Boolean(testCase))
4489
+ .filter((testCase) => baselineByName.has(testCase.name));
4490
+ if (preferred.length > 0) {
4491
+ return preferred;
4492
+ }
4493
+ return queryCases
4494
+ .filter((testCase) => baselineByName.has(testCase.name))
4495
+ .slice(0, Math.min(4, queryCases.length));
4496
+ }
697
4497
  async function runRdfModelsShadowBenchmark(engine, compatibilityStore, options = {}) {
698
4498
  const scale = options.scale ?? 'small';
699
4499
  const iterations = Math.max(1, Math.floor(options.iterations ?? 1));
700
- const cases = (options.cases ?? exports.rdfModelsBenchmarkCases)
4500
+ const caseProfile = options.caseProfile ?? 'default';
4501
+ const cases = (options.cases ?? rdfModelsBenchmarkCasesForProfile(caseProfile))
701
4502
  .filter((testCase) => scaleRank(testCase.minScale) <= scaleRank(scale));
702
4503
  const results = [];
703
4504
  const compatibilityStats = await compatibilityStore.stats();
@@ -714,6 +4515,7 @@ async function runRdfModelsShadowBenchmark(engine, compatibilityStore, options =
714
4515
  compatibilityEngine: 'quint-store',
715
4516
  candidateEngine: 'solid-rdf',
716
4517
  scale,
4518
+ caseProfile,
717
4519
  iterations,
718
4520
  generatedAt: new Date().toISOString(),
719
4521
  matched: results.every((result) => result.matched),
@@ -734,9 +4536,10 @@ function runRdfModelsRdf3xShadowBenchmark(engine, options = {}) {
734
4536
  }
735
4537
  const scale = options.scale ?? 'small';
736
4538
  const iterations = Math.max(1, Math.floor(options.iterations ?? 1));
737
- const cases = (options.cases ?? exports.rdfModelsBenchmarkCases)
4539
+ const caseProfile = options.caseProfile ?? 'default';
4540
+ const cases = (options.cases ?? rdfModelsBenchmarkCasesForProfile(caseProfile))
738
4541
  .filter((testCase) => scaleRank(testCase.minScale) <= scaleRank(scale));
739
- const queryCases = (options.queryCases ?? exports.rdfModelsQueryBenchmarkCases)
4542
+ const queryCases = (options.queryCases ?? rdfModelsQueryBenchmarkCasesForProfile(caseProfile))
740
4543
  .filter((testCase) => scaleRank(testCase.minScale) <= scaleRank(scale));
741
4544
  const rebuild = engine.rdf3xIndex.rebuildFromCurrentQuads();
742
4545
  const results = cases.map((testCase) => runRdf3xShadowBenchmarkCase(engine, testCase, iterations));
@@ -752,6 +4555,7 @@ function runRdfModelsRdf3xShadowBenchmark(engine, options = {}) {
752
4555
  primaryEngine: 'solid-rdf',
753
4556
  candidateEngine: 'solid-rdf3x',
754
4557
  scale,
4558
+ caseProfile,
755
4559
  iterations,
756
4560
  generatedAt: new Date().toISOString(),
757
4561
  matched: supportedResults.every((result) => result.matched)
@@ -861,6 +4665,115 @@ function runQueryBenchmarkCase(engine, testCase, iterations) {
861
4665
  indexStats: engine.index.stats(),
862
4666
  };
863
4667
  }
4668
+ async function runAsyncBenchmarkCase(engine, testCase, iterations, indexStats, warmupIterations = 0) {
4669
+ const durationsMs = [];
4670
+ let metrics;
4671
+ let keys = [];
4672
+ for (let i = 0; i < warmupIterations; i += 1) {
4673
+ await engine.scan(testCase.query);
4674
+ }
4675
+ for (let i = 0; i < iterations; i += 1) {
4676
+ const start = Date.now();
4677
+ const result = await engine.scan(testCase.query);
4678
+ durationsMs.push(Math.max(0, Date.now() - start));
4679
+ metrics = result.metrics;
4680
+ keys = result.quads.map(RdfShadowComparator_1.canonicalQuadKey);
4681
+ }
4682
+ const finalMetrics = metrics ?? {
4683
+ engine: 'solid-rdf',
4684
+ indexChoice: 'not-run',
4685
+ matchedRows: 0,
4686
+ returnedRows: 0,
4687
+ durationMs: 0,
4688
+ };
4689
+ const missingPlan = missingExpectedPlan(testCase, finalMetrics);
4690
+ const execution = benchmarkExecution(finalMetrics);
4691
+ return {
4692
+ name: testCase.name,
4693
+ resource: testCase.resource,
4694
+ purpose: testCase.purpose,
4695
+ minScale: testCase.minScale,
4696
+ query: {
4697
+ pattern: serializePattern(testCase.query.pattern),
4698
+ ...(testCase.query.options ? { options: testCase.query.options } : {}),
4699
+ },
4700
+ expectedPlan: [...testCase.expectedPlan],
4701
+ planMatched: missingPlan.length === 0,
4702
+ missingPlan,
4703
+ ...execution,
4704
+ returnedRows: keys.length,
4705
+ checksum: checksum(keys, false),
4706
+ orderedChecksum: checksum(keys, true),
4707
+ durationsMs,
4708
+ p50DurationMs: percentile(durationsMs, 0.5),
4709
+ p95DurationMs: percentile(durationsMs, 0.95),
4710
+ metrics: finalMetrics,
4711
+ indexStats,
4712
+ };
4713
+ }
4714
+ async function runAsyncQueryBenchmarkCase(engine, testCase, iterations, indexStats, warmupIterations = 0) {
4715
+ const durationsMs = [];
4716
+ let metrics;
4717
+ let keys = [];
4718
+ const query = asyncBenchmarkQueryFor(testCase);
4719
+ const effectiveWarmupIterations = Math.max(warmupIterations, Math.max(0, Math.floor(testCase.minWarmupIterations ?? 0)));
4720
+ for (let i = 0; i < effectiveWarmupIterations; i += 1) {
4721
+ await engine.query(query);
4722
+ }
4723
+ for (let i = 0; i < iterations; i += 1) {
4724
+ const start = Date.now();
4725
+ const result = await engine.query(query);
4726
+ durationsMs.push(Math.max(0, Date.now() - start));
4727
+ metrics = result.metrics;
4728
+ keys = result.bindings.map(bindingKey);
4729
+ }
4730
+ const finalMetrics = metrics ?? {
4731
+ engine: 'solid-rdf',
4732
+ plan: [],
4733
+ scannedRows: 0,
4734
+ joinedRows: 0,
4735
+ returnedRows: 0,
4736
+ durationMs: 0,
4737
+ indexChoices: [],
4738
+ filtersApplied: 0,
4739
+ filtersPushedDown: 0,
4740
+ };
4741
+ const missingPlan = missingExpectedQueryPlan(testCase, finalMetrics, keys.length);
4742
+ return {
4743
+ name: testCase.name,
4744
+ resource: testCase.resource,
4745
+ purpose: testCase.purpose,
4746
+ minScale: testCase.minScale,
4747
+ query: serializeQueryPlan(query),
4748
+ expectedPlan: [...testCase.expectedPlan],
4749
+ planMatched: missingPlan.length === 0,
4750
+ missingPlan,
4751
+ physicalPlan: finalMetrics.plan,
4752
+ scannedRows: finalMetrics.scannedRows,
4753
+ indexChoices: [...finalMetrics.indexChoices],
4754
+ fallbackReason: null,
4755
+ returnedRows: keys.length,
4756
+ checksum: checksum(keys, false),
4757
+ orderedChecksum: checksum(keys, true),
4758
+ durationsMs,
4759
+ p50DurationMs: percentile(durationsMs, 0.5),
4760
+ p95DurationMs: percentile(durationsMs, 0.95),
4761
+ metrics: finalMetrics,
4762
+ indexStats,
4763
+ };
4764
+ }
4765
+ function asyncBenchmarkQueryFor(testCase) {
4766
+ if (testCase.benchmarkCache === 'preserve') {
4767
+ return testCase.query;
4768
+ }
4769
+ return {
4770
+ ...testCase.query,
4771
+ cache: {
4772
+ ...(testCase.query.cache ?? {}),
4773
+ mode: 'bypass',
4774
+ },
4775
+ };
4776
+ }
864
4777
  function runRdf3xShadowBenchmarkCase(engine, testCase, iterations) {
865
4778
  const baseResult = baseRdf3xShadowBenchmarkResult(testCase);
866
4779
  const unsupportedReason = unsupportedRdf3xPatternReason(testCase.query.pattern);
@@ -1676,16 +5589,30 @@ function matchesExpectedPlanLabel(label, testCase, metrics) {
1676
5589
  const planText = (metrics.queryPlan ?? []).join('\n');
1677
5590
  switch (label) {
1678
5591
  case 'graph-scope':
1679
- return Boolean(pattern.graph) && metrics.indexChoice.includes('G');
5592
+ return Boolean(pattern.graph)
5593
+ && (metrics.indexChoice.includes('G')
5594
+ || metrics.indexChoice === 'source-membership'
5595
+ || planText.includes('GraphPrefixMembershipFilter')
5596
+ || planText.includes('GraphMembershipFilter')
5597
+ || planText.includes('Rdf3xMembershipScan')
5598
+ || planText.includes('scan.graph_prefix'));
1680
5599
  case 'type-filter':
1681
5600
  return (0, types_1.isTerm)(pattern.predicate)
1682
5601
  && (0, n3_2.termToId)(pattern.predicate) === RDF_TYPE
1683
5602
  && Boolean(pattern.object)
1684
- && metrics.indexChoice !== 'full-scan';
5603
+ && metrics.indexChoice !== 'full-scan'
5604
+ && metrics.indexChoice !== 'facts-post-filter';
1685
5605
  case 'predicate-filter':
1686
- return Boolean(pattern.predicate) && metrics.indexChoice.includes('P');
5606
+ return Boolean(pattern.predicate)
5607
+ && (metrics.indexChoice.includes('P')
5608
+ || metrics.indexChoice === 'source-membership'
5609
+ || planText.includes('Rdf3xPermutationScan('));
1687
5610
  case 'predicate-object-filter':
1688
- return Boolean(pattern.predicate) && Boolean(pattern.object) && metrics.indexChoice.includes('P');
5611
+ return Boolean(pattern.predicate)
5612
+ && Boolean(pattern.object)
5613
+ && (metrics.indexChoice.includes('P')
5614
+ || metrics.indexChoice === 'source-membership'
5615
+ || planText.includes('Rdf3xPermutationScan('));
1689
5616
  case 'predicate-object-range-filter':
1690
5617
  return Boolean(pattern.predicate)
1691
5618
  && (planText.includes('_range') || planText.includes('LexicalRange(') || planText.includes('NumericRange('));
@@ -1704,7 +5631,25 @@ function matchesExpectedPlanLabel(label, testCase, metrics) {
1704
5631
  case 'GSPO':
1705
5632
  case 'GPOS':
1706
5633
  case 'OSPG':
1707
- return metrics.indexChoice === label;
5634
+ return metrics.indexChoice === label || matchesPgPermutationPlan(label, testCase, metrics);
5635
+ default:
5636
+ return false;
5637
+ }
5638
+ }
5639
+ function matchesPgPermutationPlan(label, testCase, metrics) {
5640
+ const planText = (metrics.queryPlan ?? []).join('\n');
5641
+ const graphScoped = matchesExpectedPlanLabel('graph-scope', testCase, metrics);
5642
+ switch (label) {
5643
+ case 'SPOG':
5644
+ return metrics.indexChoice === 'SPO' || planText.includes('Rdf3xPermutationScan(SPO)');
5645
+ case 'POSG':
5646
+ return metrics.indexChoice === 'POS' || planText.includes('Rdf3xPermutationScan(POS)');
5647
+ case 'OSPG':
5648
+ return metrics.indexChoice === 'OSP' || planText.includes('Rdf3xPermutationScan(OSP)');
5649
+ case 'GSPO':
5650
+ return graphScoped && (metrics.indexChoice === 'SPO' || planText.includes('Rdf3xPermutationScan(SPO)'));
5651
+ case 'GPOS':
5652
+ return graphScoped && (metrics.indexChoice === 'POS' || planText.includes('Rdf3xPermutationScan(POS)'));
1708
5653
  default:
1709
5654
  return false;
1710
5655
  }
@@ -1788,43 +5733,142 @@ function minimumReturnedRowsFailures(testCase, returnedRows) {
1788
5733
  function matchesExpectedQueryPlanLabel(label, metrics) {
1789
5734
  const planText = metrics.plan.join('\n');
1790
5735
  switch (label) {
5736
+ case 'materialized-cache-hit':
5737
+ return planText.includes('PostgresMaterializedResultHit');
5738
+ case 'materialized-cache-miss':
5739
+ return planText.includes('PostgresMaterializedResultMiss')
5740
+ || planText.includes('PostgresMaterializedResultRefresh');
5741
+ case 'materialized-cache-store':
5742
+ return planText.includes('PostgresMaterializedResultStore');
5743
+ case 'query-template-cache-hit':
5744
+ return planText.includes('PostgresQueryTemplateCacheHit');
5745
+ case 'query-template-cache-miss':
5746
+ return planText.includes('PostgresQueryTemplateCacheMiss');
5747
+ case 'query-template-cache-bypass':
5748
+ return planText.includes('PostgresQueryTemplateCacheBypass');
1791
5749
  case 'group-count-index':
1792
- return planText.includes('Aggregate(group-count-index)');
5750
+ return planText.includes('Aggregate(group-count-index)')
5751
+ || planText.includes('PostgresRdf3xGroupCount');
1793
5752
  case 'group-aggregate-index':
1794
5753
  return planText.includes('Aggregate(group-basic-multi-index)')
1795
- || planText.includes('Aggregate(group-basic-index)');
5754
+ || planText.includes('Aggregate(group-basic-index)')
5755
+ || planText.includes('Aggregate(group-basic-multi)')
5756
+ || planText.includes('Aggregate(group-basic)')
5757
+ || planText.includes('PostgresRdf3xGroupAggregate');
5758
+ case 'join-aggregate-index':
5759
+ return ((planText.includes('Aggregate(join-basic-multi-index)')
5760
+ || planText.includes('Aggregate(join-basic-index)'))
5761
+ && (planText.includes('IndexJoinAggregate(')
5762
+ || planText.includes('Rdf3xPrimaryJoinAggregate('))) || planText.includes('PostgresRdf3xJoinAggregate');
5763
+ case 'numeric-aggregate':
5764
+ return planText.includes('JoinGroupAggregateNumeric(')
5765
+ || planText.includes('Aggregate(group-basic-multi)')
5766
+ || planText.includes('Aggregate(group-basic-index)')
5767
+ || planText.includes('Rdf3xJoinGroupAggregateNumeric(')
5768
+ || planText.includes('PostgresRdf3xGroupAggregate')
5769
+ || planText.includes('PostgresNumericAggregateFactsCutover(');
5770
+ case 'numeric-aggregate-facts-cutover':
5771
+ return planText.includes('PostgresFactsQuery')
5772
+ && planText.includes('PostgresNumericAggregateFactsCutover(')
5773
+ && !planText.includes('PostgresRdf3xGroupAggregate');
1796
5774
  case 'having-pushdown':
1797
5775
  return (planText.includes('IndexGroupCountHaving(')
1798
- || planText.includes('IndexGroupAggregateHaving('))
1799
- && !planText.includes('\nHaving(');
5776
+ || planText.includes('IndexGroupAggregateHaving(')
5777
+ || planText.includes('PostgresRdf3xAggregateHaving(')
5778
+ || planText.includes('PostgresRdfNativeCustomIndexAggregateHaving('))
5779
+ && !planText.includes('\nHaving(')
5780
+ && !planText.includes('\nPostgresFactsHaving(');
1800
5781
  case 'order':
1801
5782
  return (planText.includes('IndexGroupCountOrder(')
1802
- || planText.includes('IndexGroupAggregateOrder('))
1803
- && !planText.includes('\nSort');
5783
+ || planText.includes('IndexGroupAggregateOrder(')
5784
+ || planText.includes('PostgresRdf3xAggregateOrder(')
5785
+ || planText.includes('PostgresRdfNativeCustomIndexAggregateOrder('))
5786
+ && !planText.includes('\nSort')
5787
+ && !planText.includes('\nPostgresFactsSort(');
1804
5788
  case 'limit':
1805
5789
  return (planText.includes('IndexGroupCountLimit')
1806
- || planText.includes('IndexGroupAggregateLimit'))
1807
- && !planText.includes('\nLimit');
5790
+ || planText.includes('IndexGroupAggregateLimit')
5791
+ || planText.includes('PostgresRdf3xAggregateLimit')
5792
+ || planText.includes('PostgresRdfNativeCustomIndexAggregateLimit'))
5793
+ && !planText.includes('\nLimit')
5794
+ && !planText.includes('\nPostgresFactsLimit');
1808
5795
  case 'join-index':
1809
5796
  return planText.includes('IndexJoin(')
1810
- && !planText.includes('\nIndexScan(');
5797
+ && !planText.includes('\nIndexScan(')
5798
+ || planText.includes('PostgresRdf3xJoin(')
5799
+ || planText.includes('PostgresRdfNativeCustomIndexBgpJoin(')
5800
+ || planText.includes('PostgresRdfNativeCustomIndexValuesJoin(')
5801
+ || localIndexScanCount(planText) >= 2;
5802
+ case 'subject-star-join':
5803
+ return planText.includes('SubjectStarJoin(')
5804
+ || planText.includes('PostgresRdf3xSubjectStarJoin(')
5805
+ || planText.includes('PostgresRdfNativeCustomIndexSubjectStar');
5806
+ case 'values-recheck':
5807
+ return (planText.includes('Rdf3xJoinTupleValues(') || planText.includes('Values('))
5808
+ && !planText.includes('PostgresFactsValues(');
5809
+ case 'values-join-pushdown':
5810
+ return (planText.includes('Rdf3xJoinTupleValues(') || planText.includes('Values('))
5811
+ && !planText.includes('PostgresFactsValues(');
1811
5812
  case 'join-order-pushdown':
1812
- return planText.includes('IndexJoinOrder(')
1813
- && !planText.includes('\nSort');
5813
+ return (planText.includes('IndexJoinOrder(')
5814
+ || planText.includes('Rdf3xJoinOrder(')
5815
+ || planText.includes('Rdf3xJoinOrderBy(')
5816
+ || planText.includes('PostgresRdfNativeCustomIndexBgpOrderPage('))
5817
+ && !planText.includes('\nSort')
5818
+ && !planText.includes('\nPostgresFactsSort(');
1814
5819
  case 'join-limit-pushdown':
1815
- return planText.includes('IndexJoinLimit')
1816
- && !planText.includes('\nLimit');
5820
+ return (planText.includes('IndexJoinLimit')
5821
+ || planText.includes('Rdf3xJoinLimit')
5822
+ || planText.includes('PostgresRdf3xJoinLimit')
5823
+ || planText.includes('PostgresRdfNativeCustomIndexBgpLimit')
5824
+ || planText.includes('PostgresRdfNativeCustomIndexValuesJoinLimit'))
5825
+ && !planText.includes('\nLimit')
5826
+ && !planText.includes('\nPostgresFactsLimit');
1817
5827
  case 'range-filter-pushdown':
1818
- return metrics.filtersPushedDown > 0
1819
- && planText.includes('LexicalRange(');
5828
+ return (metrics.filtersPushedDown > 0 || planText.includes('PostgresMaterializedResultHit'))
5829
+ && (planText.includes('LexicalRange(') || planText.includes('NumericRange('));
1820
5830
  case 'join-count-index':
1821
5831
  return planText.includes('Aggregate(join-count-distinct-index)')
1822
5832
  && planText.includes('IndexJoinCount(')
1823
- && !planText.includes('\nIndexScan(');
5833
+ && !planText.includes('\nIndexScan(')
5834
+ || planText.includes('PostgresRdf3xJoinCount');
5835
+ case 'text-search-source':
5836
+ return planText.includes('TextSearch(')
5837
+ && metrics.indexChoices.includes('text-chunk');
5838
+ case 'vector-search-source':
5839
+ return planText.includes('VectorSearch(')
5840
+ && metrics.indexChoices.includes('vector-chunk');
5841
+ case 'search-rdf-join':
5842
+ return planText.includes('TextSearch(')
5843
+ && planText.includes('VectorSearch(')
5844
+ && (planText.includes('IndexJoin(')
5845
+ || planText.includes('PostgresRdf3xJoin(')
5846
+ || planText.includes('PostgresFactsScan(')
5847
+ || localIndexScanCount(planText) >= 1);
5848
+ case 'planner-source-estimates':
5849
+ return planText.includes('SourceEstimate(RdfBgpSource#')
5850
+ && planText.includes('SourceEstimate(TextMatchSource#')
5851
+ && planText.includes('SourceEstimate(VectorMatchSource#')
5852
+ && planText.includes('SourceEstimate(PathScopeSource#')
5853
+ && planText.includes('SourceEstimate(AclScopeSource#');
5854
+ case 'fusion-rank-inputs':
5855
+ return planText.includes('FusionRankInputs(text:?textScore,vector:?vectorScore,output:?fusionScore)');
5856
+ case 'fusion-rank-weights':
5857
+ return planText.includes('FusionRankWeights(text:0.55,vector:0.45,output:?fusionScore)');
5858
+ case 'fusion-rank-tiebreaker':
5859
+ return planText.includes('FusionRankTieBreaker(asc:?message)');
5860
+ case 'fusion-hard-filters-before-rank':
5861
+ return planText.includes('FusionHardFiltersBeforeRank(path,acl,output:?fusionScore)');
5862
+ case 'search-score-rerank':
5863
+ return planText.includes('Bind(?fusionScore:=')
5864
+ && planText.includes('Sort');
1824
5865
  default:
1825
5866
  return false;
1826
5867
  }
1827
5868
  }
5869
+ function localIndexScanCount(planText) {
5870
+ return planText.match(/\bIndexScan\(/g)?.length ?? 0;
5871
+ }
1828
5872
  function missingExpectedRdf3xJoinPlan(testCase, metrics, returnedRows) {
1829
5873
  return [
1830
5874
  ...testCase.expectedPlan.filter((label) => !matchesExpectedRdf3xJoinPlanLabel(label, metrics)),
@@ -1840,6 +5884,12 @@ function matchesExpectedRdf3xJoinPlanLabel(label, metrics) {
1840
5884
  case 'group-aggregate-index':
1841
5885
  return planText.includes('Rdf3xJoinGroupAggregate(')
1842
5886
  || planText.includes('Rdf3xJoinGroupAggregateNumeric(');
5887
+ case 'numeric-aggregate':
5888
+ return planText.includes('Rdf3xJoinGroupAggregateNumeric(')
5889
+ || planText.includes('Rdf3xJoinAggregateNumeric(');
5890
+ case 'join-aggregate-index':
5891
+ return planText.includes('Rdf3xJoinAggregate(')
5892
+ || planText.includes('Rdf3xJoinAggregateNumeric(');
1843
5893
  case 'having-pushdown':
1844
5894
  return planText.includes('Rdf3xJoinGroupCountHaving(')
1845
5895
  || planText.includes('Rdf3xJoinGroupAggregateHaving(');
@@ -1851,6 +5901,8 @@ function matchesExpectedRdf3xJoinPlanLabel(label, metrics) {
1851
5901
  || planText.includes('Rdf3xJoinGroupAggregateLimit');
1852
5902
  case 'join-index':
1853
5903
  return planText.includes('Rdf3xJoinBGP(');
5904
+ case 'subject-star-join':
5905
+ return planText.includes('SubjectStarJoin(');
1854
5906
  case 'join-order-pushdown':
1855
5907
  return planText.includes('Rdf3xJoinOrder(');
1856
5908
  case 'join-limit-pushdown':