@abloatai/ablo 0.35.0 → 0.37.0

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 (622) hide show
  1. package/AGENTS.md +2 -2
  2. package/CHANGELOG.md +71 -1929
  3. package/NOTICE +2 -2
  4. package/README.md +23 -532
  5. package/assets/banner.png +0 -0
  6. package/dist/auth.d.ts +2 -0
  7. package/dist/auth.d.ts.map +1 -0
  8. package/dist/auth.js +2 -0
  9. package/dist/auth.js.map +1 -0
  10. package/dist/client.d.ts +3 -0
  11. package/dist/client.d.ts.map +1 -0
  12. package/dist/client.js +3 -0
  13. package/dist/client.js.map +1 -0
  14. package/dist/coordination.d.ts +2 -0
  15. package/dist/coordination.d.ts.map +1 -0
  16. package/dist/coordination.js +2 -0
  17. package/dist/coordination.js.map +1 -0
  18. package/dist/index.d.ts +3 -112
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +3 -161
  21. package/dist/index.js.map +1 -0
  22. package/dist/react.d.ts +4 -0
  23. package/dist/react.d.ts.map +1 -0
  24. package/dist/react.js +3 -0
  25. package/dist/react.js.map +1 -0
  26. package/dist/schema.d.ts +2 -0
  27. package/dist/schema.d.ts.map +1 -0
  28. package/dist/schema.js +2 -0
  29. package/dist/schema.js.map +1 -0
  30. package/dist/server.d.ts +2 -0
  31. package/dist/server.d.ts.map +1 -0
  32. package/dist/server.js +2 -0
  33. package/dist/server.js.map +1 -0
  34. package/dist/source-conformance.d.ts +2 -0
  35. package/dist/source-conformance.d.ts.map +1 -0
  36. package/dist/source-conformance.js +2 -0
  37. package/dist/source-conformance.js.map +1 -0
  38. package/dist/source-drizzle.d.ts +2 -0
  39. package/dist/source-drizzle.d.ts.map +1 -0
  40. package/dist/source-drizzle.js +2 -0
  41. package/dist/source-drizzle.js.map +1 -0
  42. package/dist/source-kysely.d.ts +2 -0
  43. package/dist/source-kysely.d.ts.map +1 -0
  44. package/dist/source-kysely.js +2 -0
  45. package/dist/source-kysely.js.map +1 -0
  46. package/dist/source-next.d.ts +2 -0
  47. package/dist/source-next.d.ts.map +1 -0
  48. package/dist/source-next.js +2 -0
  49. package/dist/source-next.js.map +1 -0
  50. package/dist/source.d.ts +2 -0
  51. package/dist/source.d.ts.map +1 -0
  52. package/dist/source.js +2 -0
  53. package/dist/source.js.map +1 -0
  54. package/dist/wire.d.ts +2 -0
  55. package/dist/wire.d.ts.map +1 -0
  56. package/dist/wire.js +2 -0
  57. package/dist/wire.js.map +1 -0
  58. package/docs/agents.md +2 -2
  59. package/docs/api-keys.md +13 -12
  60. package/docs/api.md +15 -53
  61. package/docs/audit.md +4 -3
  62. package/docs/cli.md +11 -11
  63. package/docs/client-behavior.md +9 -9
  64. package/docs/concurrency-convention.md +28 -42
  65. package/docs/coordination.md +228 -86
  66. package/docs/data-sources.md +5 -5
  67. package/docs/debugging.md +34 -12
  68. package/docs/deployment.md +8 -8
  69. package/docs/examples/agent-human.md +4 -4
  70. package/docs/examples/ai-sdk-tool.md +1 -1
  71. package/docs/examples/existing-python-backend.md +15 -4
  72. package/docs/examples/nextjs.md +27 -6
  73. package/docs/examples/scoped-agent.md +3 -3
  74. package/docs/examples/server-agent.md +2 -2
  75. package/docs/groups.md +57 -3
  76. package/docs/guarantees.md +37 -10
  77. package/docs/how-it-works.md +32 -8
  78. package/docs/idempotency.md +6 -6
  79. package/docs/identity.md +24 -24
  80. package/docs/index.md +8 -8
  81. package/docs/integration-guide.md +38 -16
  82. package/docs/internal/README.md +18 -0
  83. package/docs/internal/agent-fleet-coordination-design.md +171 -0
  84. package/docs/internal/agent-orchestration.md +58 -0
  85. package/docs/internal/commit-identifiers.md +91 -0
  86. package/docs/internal/concurrency-open-decisions.md +37 -0
  87. package/docs/internal/data-source-reverse-channel.md +150 -0
  88. package/docs/internal/per-field-conflict-detection.md +165 -0
  89. package/docs/internal/postgres-replication.md +64 -0
  90. package/docs/internal/serializable-schema.md +119 -0
  91. package/docs/internal/structure.md +32 -0
  92. package/docs/mcp.md +9 -9
  93. package/docs/migration.md +37 -18
  94. package/docs/projects.md +1 -1
  95. package/docs/quickstart.md +2 -2
  96. package/docs/react.md +24 -13
  97. package/docs/schema-contract.md +3 -3
  98. package/docs/sessions.md +91 -37
  99. package/docs/webhooks.md +9 -9
  100. package/examples/README.md +2 -2
  101. package/examples/data-source/README.md +1 -1
  102. package/examples/data-source/ablo-driver.ts +1 -1
  103. package/examples/data-source/customer-server.ts +1 -1
  104. package/examples/data-source/run.ts +1 -1
  105. package/examples/data-source/schema.ts +1 -1
  106. package/examples/quickstart.ts +2 -2
  107. package/llms.txt +12 -12
  108. package/package.json +64 -174
  109. package/dist/BaseSyncedStore.d.ts +0 -823
  110. package/dist/BaseSyncedStore.js +0 -1955
  111. package/dist/Database.d.ts +0 -335
  112. package/dist/Database.js +0 -1500
  113. package/dist/InstanceCache.d.ts +0 -233
  114. package/dist/InstanceCache.js +0 -1164
  115. package/dist/LazyReferenceCollection.d.ts +0 -177
  116. package/dist/LazyReferenceCollection.js +0 -461
  117. package/dist/Model.d.ts +0 -444
  118. package/dist/Model.js +0 -909
  119. package/dist/ModelRegistry.d.ts +0 -221
  120. package/dist/ModelRegistry.js +0 -537
  121. package/dist/NetworkMonitor.d.ts +0 -26
  122. package/dist/NetworkMonitor.js +0 -77
  123. package/dist/RuntimeContext.d.ts +0 -52
  124. package/dist/RuntimeContext.js +0 -80
  125. package/dist/SyncClient.d.ts +0 -551
  126. package/dist/SyncClient.js +0 -2199
  127. package/dist/adapters/alwaysOnline.d.ts +0 -14
  128. package/dist/adapters/alwaysOnline.js +0 -17
  129. package/dist/adapters/inMemoryStorage.d.ts +0 -31
  130. package/dist/adapters/inMemoryStorage.js +0 -110
  131. package/dist/ai-sdk/coordinatedTool.d.ts +0 -120
  132. package/dist/ai-sdk/coordinatedTool.js +0 -134
  133. package/dist/ai-sdk/coordinationContext.d.ts +0 -46
  134. package/dist/ai-sdk/coordinationContext.js +0 -106
  135. package/dist/ai-sdk/index.d.ts +0 -121
  136. package/dist/ai-sdk/index.js +0 -121
  137. package/dist/ai-sdk/wrap.d.ts +0 -65
  138. package/dist/ai-sdk/wrap.js +0 -39
  139. package/dist/auth/index.d.ts +0 -1
  140. package/dist/auth/index.js +0 -8
  141. package/dist/batching/index.d.ts +0 -55
  142. package/dist/batching/index.js +0 -147
  143. package/dist/cli.cjs +0 -288600
  144. package/dist/client/Ablo.d.ts +0 -231
  145. package/dist/client/Ablo.js +0 -149
  146. package/dist/client/abloClient.d.ts +0 -309
  147. package/dist/client/abloClient.js +0 -13
  148. package/dist/client/clientPrelude.d.ts +0 -52
  149. package/dist/client/clientPrelude.js +0 -60
  150. package/dist/client/consoleLogger.d.ts +0 -35
  151. package/dist/client/consoleLogger.js +0 -44
  152. package/dist/client/coreClient.d.ts +0 -60
  153. package/dist/client/coreClient.js +0 -118
  154. package/dist/client/createInternalComponents.d.ts +0 -46
  155. package/dist/client/createInternalComponents.js +0 -92
  156. package/dist/client/createModelProxy.d.ts +0 -228
  157. package/dist/client/createModelProxy.js +0 -818
  158. package/dist/client/humans.d.ts +0 -48
  159. package/dist/client/humans.js +0 -52
  160. package/dist/client/modelRegistration.d.ts +0 -10
  161. package/dist/client/modelRegistration.js +0 -312
  162. package/dist/client/options.d.ts +0 -461
  163. package/dist/client/options.js +0 -7
  164. package/dist/client/reactiveEngine.d.ts +0 -48
  165. package/dist/client/reactiveEngine.js +0 -910
  166. package/dist/client/resourceTypes.d.ts +0 -12
  167. package/dist/client/resourceTypes.js +0 -10
  168. package/dist/client/schemaConfig.d.ts +0 -44
  169. package/dist/client/schemaConfig.js +0 -185
  170. package/dist/client/validateAbloOptions.d.ts +0 -42
  171. package/dist/client/validateAbloOptions.js +0 -43
  172. package/dist/client/wsMutationExecutor.d.ts +0 -27
  173. package/dist/client/wsMutationExecutor.js +0 -72
  174. package/dist/context.d.ts +0 -29
  175. package/dist/context.js +0 -58
  176. package/dist/coordination/ClaimLog.d.ts +0 -26
  177. package/dist/coordination/ClaimLog.js +0 -32
  178. package/dist/coordination/index.d.ts +0 -1
  179. package/dist/coordination/index.js +0 -8
  180. package/dist/core/DatabaseManager.d.ts +0 -105
  181. package/dist/core/DatabaseManager.js +0 -387
  182. package/dist/core/QueryProcessor.d.ts +0 -75
  183. package/dist/core/QueryProcessor.js +0 -255
  184. package/dist/core/QueryView.d.ts +0 -79
  185. package/dist/core/QueryView.js +0 -218
  186. package/dist/core/StoreManager.d.ts +0 -112
  187. package/dist/core/StoreManager.js +0 -302
  188. package/dist/core/ViewRegistry.d.ts +0 -20
  189. package/dist/core/ViewRegistry.js +0 -55
  190. package/dist/core/index.d.ts +0 -33
  191. package/dist/core/index.js +0 -48
  192. package/dist/core/openIDBWithTimeout.d.ts +0 -65
  193. package/dist/core/openIDBWithTimeout.js +0 -153
  194. package/dist/core/queryUtils.d.ts +0 -45
  195. package/dist/core/queryUtils.js +0 -69
  196. package/dist/core/storeContract.d.ts +0 -145
  197. package/dist/core/storeContract.js +0 -12
  198. package/dist/docs/catalog.d.ts +0 -72
  199. package/dist/docs/catalog.js +0 -227
  200. package/dist/docs/index.d.ts +0 -10
  201. package/dist/docs/index.js +0 -10
  202. package/dist/environment.d.ts +0 -1
  203. package/dist/environment.js +0 -8
  204. package/dist/interfaces/index.d.ts +0 -311
  205. package/dist/interfaces/index.js +0 -9
  206. package/dist/keys/index.d.ts +0 -1
  207. package/dist/keys/index.js +0 -8
  208. package/dist/mutators/RecordingMutation.d.ts +0 -36
  209. package/dist/mutators/RecordingMutation.js +0 -182
  210. package/dist/mutators/Transaction.d.ts +0 -40
  211. package/dist/mutators/Transaction.js +0 -58
  212. package/dist/mutators/UndoManager.d.ts +0 -258
  213. package/dist/mutators/UndoManager.js +0 -658
  214. package/dist/mutators/defineMutators.d.ts +0 -60
  215. package/dist/mutators/defineMutators.js +0 -18
  216. package/dist/mutators/inverseOp.d.ts +0 -126
  217. package/dist/mutators/inverseOp.js +0 -71
  218. package/dist/mutators/mutateActions.d.ts +0 -45
  219. package/dist/mutators/mutateActions.js +0 -105
  220. package/dist/mutators/readerActions.d.ts +0 -33
  221. package/dist/mutators/readerActions.js +0 -57
  222. package/dist/mutators/undoApply.d.ts +0 -51
  223. package/dist/mutators/undoApply.js +0 -117
  224. package/dist/policy/index.d.ts +0 -21
  225. package/dist/policy/index.js +0 -20
  226. package/dist/query/client.d.ts +0 -61
  227. package/dist/query/client.js +0 -137
  228. package/dist/query/types.d.ts +0 -85
  229. package/dist/query/types.js +0 -16
  230. package/dist/react/AbloProvider.d.ts +0 -230
  231. package/dist/react/AbloProvider.js +0 -455
  232. package/dist/react/ClientSideSuspense.d.ts +0 -36
  233. package/dist/react/ClientSideSuspense.js +0 -17
  234. package/dist/react/DefaultFallback.d.ts +0 -24
  235. package/dist/react/DefaultFallback.js +0 -43
  236. package/dist/react/context.d.ts +0 -55
  237. package/dist/react/context.js +0 -29
  238. package/dist/react/index.d.ts +0 -61
  239. package/dist/react/index.js +0 -66
  240. package/dist/react/internalContext.d.ts +0 -33
  241. package/dist/react/internalContext.js +0 -3
  242. package/dist/react/useAblo.d.ts +0 -75
  243. package/dist/react/useAblo.js +0 -102
  244. package/dist/react/useCurrentUserId.d.ts +0 -22
  245. package/dist/react/useCurrentUserId.js +0 -34
  246. package/dist/react/useErrorListener.d.ts +0 -20
  247. package/dist/react/useErrorListener.js +0 -38
  248. package/dist/react/useMutationFailureListener.d.ts +0 -26
  249. package/dist/react/useMutationFailureListener.js +0 -38
  250. package/dist/react/useMutators.d.ts +0 -56
  251. package/dist/react/useMutators.js +0 -84
  252. package/dist/react/useReactive.d.ts +0 -35
  253. package/dist/react/useReactive.js +0 -123
  254. package/dist/react/useSyncStatus.d.ts +0 -59
  255. package/dist/react/useSyncStatus.js +0 -76
  256. package/dist/react/useUndoScope.d.ts +0 -34
  257. package/dist/react/useUndoScope.js +0 -81
  258. package/dist/schema/coordination.d.ts +0 -112
  259. package/dist/schema/coordination.js +0 -129
  260. package/dist/schema/ddl.d.ts +0 -97
  261. package/dist/schema/ddl.js +0 -491
  262. package/dist/schema/ddlLock.d.ts +0 -35
  263. package/dist/schema/ddlLock.js +0 -46
  264. package/dist/schema/diff.d.ts +0 -225
  265. package/dist/schema/diff.js +0 -289
  266. package/dist/schema/generate.d.ts +0 -19
  267. package/dist/schema/generate.js +0 -86
  268. package/dist/schema/index.d.ts +0 -41
  269. package/dist/schema/index.js +0 -76
  270. package/dist/schema/queries.d.ts +0 -201
  271. package/dist/schema/queries.js +0 -144
  272. package/dist/schema/select.d.ts +0 -40
  273. package/dist/schema/select.js +0 -87
  274. package/dist/schema/serialize.d.ts +0 -115
  275. package/dist/schema/serialize.js +0 -262
  276. package/dist/schema/sugar.d.ts +0 -109
  277. package/dist/schema/sugar.js +0 -83
  278. package/dist/schema/syncDeltaRow.d.ts +0 -6
  279. package/dist/schema/syncDeltaRow.js +0 -6
  280. package/dist/server/adapter.d.ts +0 -173
  281. package/dist/server/adapter.js +0 -18
  282. package/dist/server/commit.d.ts +0 -107
  283. package/dist/server/commit.js +0 -1
  284. package/dist/server/index.d.ts +0 -14
  285. package/dist/server/index.js +0 -2
  286. package/dist/server/readConfig.d.ts +0 -80
  287. package/dist/server/readConfig.js +0 -8
  288. package/dist/server/storageMode.d.ts +0 -23
  289. package/dist/server/storageMode.js +0 -17
  290. package/dist/source/adapter.d.ts +0 -81
  291. package/dist/source/adapter.js +0 -22
  292. package/dist/source/adapters/drizzle.d.ts +0 -48
  293. package/dist/source/adapters/drizzle.js +0 -219
  294. package/dist/source/adapters/kysely.d.ts +0 -42
  295. package/dist/source/adapters/kysely.js +0 -205
  296. package/dist/source/adapters/kyselyMutationCore.d.ts +0 -76
  297. package/dist/source/adapters/kyselyMutationCore.js +0 -125
  298. package/dist/source/adapters/memory.d.ts +0 -13
  299. package/dist/source/adapters/memory.js +0 -130
  300. package/dist/source/adapters/prisma.d.ts +0 -63
  301. package/dist/source/adapters/prisma.js +0 -202
  302. package/dist/source/conformance.d.ts +0 -37
  303. package/dist/source/conformance.js +0 -215
  304. package/dist/source/connector.d.ts +0 -95
  305. package/dist/source/connector.js +0 -266
  306. package/dist/source/connectorProtocol.d.ts +0 -154
  307. package/dist/source/connectorProtocol.js +0 -163
  308. package/dist/source/contract.d.ts +0 -195
  309. package/dist/source/contract.js +0 -164
  310. package/dist/source/factory.d.ts +0 -92
  311. package/dist/source/factory.js +0 -286
  312. package/dist/source/footprint.d.ts +0 -111
  313. package/dist/source/footprint.js +0 -0
  314. package/dist/source/idempotency.d.ts +0 -61
  315. package/dist/source/idempotency.js +0 -144
  316. package/dist/source/index.d.ts +0 -23
  317. package/dist/source/index.js +0 -30
  318. package/dist/source/migrations.d.ts +0 -21
  319. package/dist/source/migrations.js +0 -103
  320. package/dist/source/next.d.ts +0 -32
  321. package/dist/source/next.js +0 -25
  322. package/dist/source/pushQueue.d.ts +0 -134
  323. package/dist/source/pushQueue.js +0 -256
  324. package/dist/source/signing.d.ts +0 -92
  325. package/dist/source/signing.js +0 -162
  326. package/dist/source/types.d.ts +0 -401
  327. package/dist/source/types.js +0 -59
  328. package/dist/stores/ObjectStore.d.ts +0 -115
  329. package/dist/stores/ObjectStore.js +0 -393
  330. package/dist/stores/ObjectStoreContract.d.ts +0 -38
  331. package/dist/stores/ObjectStoreContract.js +0 -1
  332. package/dist/stores/SyncActionStore.d.ts +0 -97
  333. package/dist/stores/SyncActionStore.js +0 -504
  334. package/dist/stores/syncAction.d.ts +0 -26
  335. package/dist/stores/syncAction.js +0 -16
  336. package/dist/surface.d.ts +0 -36
  337. package/dist/surface.js +0 -75
  338. package/dist/sync/BootstrapFetcher.d.ts +0 -280
  339. package/dist/sync/BootstrapFetcher.js +0 -962
  340. package/dist/sync/ConnectionManager.d.ts +0 -8
  341. package/dist/sync/ConnectionManager.js +0 -8
  342. package/dist/sync/OnDemandLoader.d.ts +0 -228
  343. package/dist/sync/OnDemandLoader.js +0 -742
  344. package/dist/sync/SubscriptionManager.d.ts +0 -159
  345. package/dist/sync/SubscriptionManager.js +0 -243
  346. package/dist/sync/SyncWebSocket.d.ts +0 -173
  347. package/dist/sync/SyncWebSocket.js +0 -438
  348. package/dist/sync/awaitClaimGrant.d.ts +0 -6
  349. package/dist/sync/awaitClaimGrant.js +0 -6
  350. package/dist/sync/bootstrapApply.d.ts +0 -70
  351. package/dist/sync/bootstrapApply.js +0 -73
  352. package/dist/sync/commitFrames.d.ts +0 -8
  353. package/dist/sync/commitFrames.js +0 -8
  354. package/dist/sync/contextPorts.d.ts +0 -18
  355. package/dist/sync/contextPorts.js +0 -31
  356. package/dist/sync/createClaimStream.d.ts +0 -7
  357. package/dist/sync/createClaimStream.js +0 -7
  358. package/dist/sync/createPresenceStream.d.ts +0 -69
  359. package/dist/sync/createPresenceStream.js +0 -200
  360. package/dist/sync/createSnapshot.d.ts +0 -29
  361. package/dist/sync/createSnapshot.js +0 -118
  362. package/dist/sync/credentialLifecycle.d.ts +0 -7
  363. package/dist/sync/credentialLifecycle.js +0 -7
  364. package/dist/sync/deltaPipeline.d.ts +0 -113
  365. package/dist/sync/deltaPipeline.js +0 -261
  366. package/dist/sync/groupChange.d.ts +0 -113
  367. package/dist/sync/groupChange.js +0 -242
  368. package/dist/sync/participants.d.ts +0 -115
  369. package/dist/sync/participants.js +0 -344
  370. package/dist/sync/persistedPrefix.d.ts +0 -12
  371. package/dist/sync/persistedPrefix.js +0 -22
  372. package/dist/sync/schemaDrift.d.ts +0 -55
  373. package/dist/sync/schemaDrift.js +0 -53
  374. package/dist/sync/schemas.d.ts +0 -70
  375. package/dist/sync/schemas.js +0 -94
  376. package/dist/sync/syncCursor.d.ts +0 -40
  377. package/dist/sync/syncCursor.js +0 -55
  378. package/dist/sync/syncPlan.d.ts +0 -54
  379. package/dist/sync/syncPlan.js +0 -50
  380. package/dist/sync/wsFrameHandlers.d.ts +0 -8
  381. package/dist/sync/wsFrameHandlers.js +0 -8
  382. package/dist/testing/fixtures/bootstrap.d.ts +0 -49
  383. package/dist/testing/fixtures/bootstrap.js +0 -59
  384. package/dist/testing/fixtures/deltas.d.ts +0 -83
  385. package/dist/testing/fixtures/deltas.js +0 -136
  386. package/dist/testing/fixtures/httpResponses.d.ts +0 -70
  387. package/dist/testing/fixtures/httpResponses.js +0 -90
  388. package/dist/testing/fixtures/models.d.ts +0 -83
  389. package/dist/testing/fixtures/models.js +0 -272
  390. package/dist/testing/helpers/reactWrapper.d.ts +0 -69
  391. package/dist/testing/helpers/reactWrapper.js +0 -67
  392. package/dist/testing/helpers/syncEngineHarness.d.ts +0 -54
  393. package/dist/testing/helpers/syncEngineHarness.js +0 -73
  394. package/dist/testing/helpers/wait.d.ts +0 -30
  395. package/dist/testing/helpers/wait.js +0 -49
  396. package/dist/testing/index.d.ts +0 -23
  397. package/dist/testing/index.js +0 -33
  398. package/dist/testing/mocks/FakeDatabase.d.ts +0 -18
  399. package/dist/testing/mocks/FakeDatabase.js +0 -10
  400. package/dist/testing/mocks/MockMutationExecutor.d.ts +0 -87
  401. package/dist/testing/mocks/MockMutationExecutor.js +0 -186
  402. package/dist/testing/mocks/MockNetworkMonitor.d.ts +0 -20
  403. package/dist/testing/mocks/MockNetworkMonitor.js +0 -46
  404. package/dist/testing/mocks/MockSyncContext.d.ts +0 -51
  405. package/dist/testing/mocks/MockSyncContext.js +0 -72
  406. package/dist/testing/mocks/MockSyncStore.d.ts +0 -88
  407. package/dist/testing/mocks/MockSyncStore.js +0 -171
  408. package/dist/testing/mocks/MockWebSocket.d.ts +0 -71
  409. package/dist/testing/mocks/MockWebSocket.js +0 -118
  410. package/dist/transaction/ablo.d.ts +0 -88
  411. package/dist/transaction/ablo.js +0 -33
  412. package/dist/transaction/auth/apiKey.d.ts +0 -152
  413. package/dist/transaction/auth/apiKey.js +0 -419
  414. package/dist/transaction/auth/bootstrapScope.d.ts +0 -15
  415. package/dist/transaction/auth/bootstrapScope.js +0 -1
  416. package/dist/transaction/auth/capability.d.ts +0 -177
  417. package/dist/transaction/auth/capability.js +0 -199
  418. package/dist/transaction/auth/credentialEndpoint.d.ts +0 -61
  419. package/dist/transaction/auth/credentialEndpoint.js +0 -86
  420. package/dist/transaction/auth/credentialPolicy.d.ts +0 -148
  421. package/dist/transaction/auth/credentialPolicy.js +0 -125
  422. package/dist/transaction/auth/credentialSource.d.ts +0 -30
  423. package/dist/transaction/auth/credentialSource.js +0 -55
  424. package/dist/transaction/auth/hostedEndpoints.d.ts +0 -21
  425. package/dist/transaction/auth/hostedEndpoints.js +0 -21
  426. package/dist/transaction/auth/identity.d.ts +0 -55
  427. package/dist/transaction/auth/identity.js +0 -210
  428. package/dist/transaction/auth/index.d.ts +0 -162
  429. package/dist/transaction/auth/index.js +0 -304
  430. package/dist/transaction/auth/schemas.d.ts +0 -59
  431. package/dist/transaction/auth/schemas.js +0 -85
  432. package/dist/transaction/auth/sessionMint.d.ts +0 -28
  433. package/dist/transaction/auth/sessionMint.js +0 -85
  434. package/dist/transaction/coordination/awaitClaimGrant.d.ts +0 -49
  435. package/dist/transaction/coordination/awaitClaimGrant.js +0 -112
  436. package/dist/transaction/coordination/claimHeartbeatLoop.d.ts +0 -50
  437. package/dist/transaction/coordination/claimHeartbeatLoop.js +0 -88
  438. package/dist/transaction/coordination/claimMeta.d.ts +0 -49
  439. package/dist/transaction/coordination/claimMeta.js +0 -52
  440. package/dist/transaction/coordination/createClaimStream.d.ts +0 -64
  441. package/dist/transaction/coordination/createClaimStream.js +0 -475
  442. package/dist/transaction/coordination/events.d.ts +0 -74
  443. package/dist/transaction/coordination/events.js +0 -7
  444. package/dist/transaction/coordination/index.d.ts +0 -19
  445. package/dist/transaction/coordination/index.js +0 -44
  446. package/dist/transaction/coordination/locator.d.ts +0 -83
  447. package/dist/transaction/coordination/locator.js +0 -82
  448. package/dist/transaction/coordination/schema.d.ts +0 -1473
  449. package/dist/transaction/coordination/schema.js +0 -1013
  450. package/dist/transaction/coordination/targetConflict.d.ts +0 -2
  451. package/dist/transaction/coordination/targetConflict.js +0 -103
  452. package/dist/transaction/coordination/trace.d.ts +0 -78
  453. package/dist/transaction/coordination/trace.js +0 -138
  454. package/dist/transaction/durableWrites.d.ts +0 -62
  455. package/dist/transaction/durableWrites.js +0 -71
  456. package/dist/transaction/environment.d.ts +0 -105
  457. package/dist/transaction/environment.js +0 -108
  458. package/dist/transaction/errorCodes.d.ts +0 -403
  459. package/dist/transaction/errorCodes.js +0 -480
  460. package/dist/transaction/errors.d.ts +0 -428
  461. package/dist/transaction/errors.js +0 -686
  462. package/dist/transaction/index.d.ts +0 -20
  463. package/dist/transaction/index.js +0 -20
  464. package/dist/transaction/keys/index.d.ts +0 -87
  465. package/dist/transaction/keys/index.js +0 -207
  466. package/dist/transaction/log/syncDeltaRow.d.ts +0 -158
  467. package/dist/transaction/log/syncDeltaRow.js +0 -95
  468. package/dist/transaction/logPosition.d.ts +0 -97
  469. package/dist/transaction/logPosition.js +0 -125
  470. package/dist/transaction/logger.d.ts +0 -16
  471. package/dist/transaction/logger.js +0 -7
  472. package/dist/transaction/observability.d.ts +0 -53
  473. package/dist/transaction/observability.js +0 -19
  474. package/dist/transaction/persistence.d.ts +0 -12
  475. package/dist/transaction/persistence.js +0 -11
  476. package/dist/transaction/plugin.d.ts +0 -192
  477. package/dist/transaction/plugin.js +0 -87
  478. package/dist/transaction/policy/types.d.ts +0 -217
  479. package/dist/transaction/policy/types.js +0 -126
  480. package/dist/transaction/resources/functionalUpdate.d.ts +0 -79
  481. package/dist/transaction/resources/functionalUpdate.js +0 -87
  482. package/dist/transaction/resources/httpResources.d.ts +0 -266
  483. package/dist/transaction/resources/httpResources.js +0 -7
  484. package/dist/transaction/resources/modelOperations.d.ts +0 -319
  485. package/dist/transaction/resources/modelOperations.js +0 -12
  486. package/dist/transaction/resources/mutationOptions.d.ts +0 -66
  487. package/dist/transaction/resources/mutationOptions.js +0 -9
  488. package/dist/transaction/resources/where.d.ts +0 -85
  489. package/dist/transaction/resources/where.js +0 -70
  490. package/dist/transaction/resources/writeOptionsSchema.d.ts +0 -47
  491. package/dist/transaction/resources/writeOptionsSchema.js +0 -73
  492. package/dist/transaction/schema/field.d.ts +0 -126
  493. package/dist/transaction/schema/field.js +0 -265
  494. package/dist/transaction/schema/loadStrategy.d.ts +0 -45
  495. package/dist/transaction/schema/loadStrategy.js +0 -46
  496. package/dist/transaction/schema/model.d.ts +0 -379
  497. package/dist/transaction/schema/model.js +0 -123
  498. package/dist/transaction/schema/openapi.d.ts +0 -57
  499. package/dist/transaction/schema/openapi.js +0 -340
  500. package/dist/transaction/schema/relation.d.ts +0 -199
  501. package/dist/transaction/schema/relation.js +0 -104
  502. package/dist/transaction/schema/residency.d.ts +0 -29
  503. package/dist/transaction/schema/residency.js +0 -25
  504. package/dist/transaction/schema/roles.d.ts +0 -249
  505. package/dist/transaction/schema/roles.js +0 -230
  506. package/dist/transaction/schema/schema.d.ts +0 -324
  507. package/dist/transaction/schema/schema.js +0 -305
  508. package/dist/transaction/schema/tenancy.d.ts +0 -139
  509. package/dist/transaction/schema/tenancy.js +0 -190
  510. package/dist/transaction/transactionLayer.d.ts +0 -82
  511. package/dist/transaction/transactionLayer.js +0 -24
  512. package/dist/transaction/transactions/settlement/commitEnvelope.d.ts +0 -143
  513. package/dist/transaction/transactions/settlement/commitEnvelope.js +0 -161
  514. package/dist/transaction/transactions/settlement/httpCommitEnvelope.d.ts +0 -53
  515. package/dist/transaction/transactions/settlement/httpCommitEnvelope.js +0 -207
  516. package/dist/transaction/transactions/settlement/idempotencyKey.d.ts +0 -10
  517. package/dist/transaction/transactions/settlement/idempotencyKey.js +0 -9
  518. package/dist/transaction/transactions/settlement/pendingWrite.d.ts +0 -112
  519. package/dist/transaction/transactions/settlement/pendingWrite.js +0 -20
  520. package/dist/transaction/transport/commitFrames.d.ts +0 -90
  521. package/dist/transaction/transport/commitFrames.js +0 -134
  522. package/dist/transaction/transport/connectionManager.d.ts +0 -215
  523. package/dist/transaction/transport/connectionManager.js +0 -673
  524. package/dist/transaction/transport/credentialLifecycle.d.ts +0 -177
  525. package/dist/transaction/transport/credentialLifecycle.js +0 -324
  526. package/dist/transaction/transport/heartbeat.d.ts +0 -65
  527. package/dist/transaction/transport/heartbeat.js +0 -93
  528. package/dist/transaction/transport/httpClient.d.ts +0 -123
  529. package/dist/transaction/transport/httpClient.js +0 -145
  530. package/dist/transaction/transport/httpOptions.d.ts +0 -33
  531. package/dist/transaction/transport/httpOptions.js +0 -12
  532. package/dist/transaction/transport/httpTransport.d.ts +0 -8
  533. package/dist/transaction/transport/httpTransport.js +0 -1276
  534. package/dist/transaction/transport/networkProbe.d.ts +0 -84
  535. package/dist/transaction/transport/networkProbe.js +0 -207
  536. package/dist/transaction/transport/wsFrameHandlers.d.ts +0 -128
  537. package/dist/transaction/transport/wsFrameHandlers.js +0 -429
  538. package/dist/transaction/transport/wsTransport.d.ts +0 -576
  539. package/dist/transaction/transport/wsTransport.js +0 -1017
  540. package/dist/transaction/types/assertExact.d.ts +0 -17
  541. package/dist/transaction/types/assertExact.js +0 -1
  542. package/dist/transaction/types/global.d.ts +0 -107
  543. package/dist/transaction/types/global.js +0 -40
  544. package/dist/transaction/types/index.d.ts +0 -205
  545. package/dist/transaction/types/index.js +0 -56
  546. package/dist/transaction/types/modelData.d.ts +0 -10
  547. package/dist/transaction/types/modelData.js +0 -9
  548. package/dist/transaction/types/participant.d.ts +0 -20
  549. package/dist/transaction/types/participant.js +0 -10
  550. package/dist/transaction/types/streams.d.ts +0 -540
  551. package/dist/transaction/types/streams.js +0 -11
  552. package/dist/transaction/utils/asyncIterator.d.ts +0 -34
  553. package/dist/transaction/utils/asyncIterator.js +0 -135
  554. package/dist/transaction/utils/duration.d.ts +0 -25
  555. package/dist/transaction/utils/duration.js +0 -45
  556. package/dist/transaction/utils/json.d.ts +0 -57
  557. package/dist/transaction/utils/json.js +0 -276
  558. package/dist/transaction/wire/accountResponses.d.ts +0 -351
  559. package/dist/transaction/wire/accountResponses.js +0 -255
  560. package/dist/transaction/wire/auth.d.ts +0 -49
  561. package/dist/transaction/wire/auth.js +0 -57
  562. package/dist/transaction/wire/bootstrapReason.d.ts +0 -9
  563. package/dist/transaction/wire/bootstrapReason.js +0 -8
  564. package/dist/transaction/wire/claimEvent.d.ts +0 -76
  565. package/dist/transaction/wire/claimEvent.js +0 -73
  566. package/dist/transaction/wire/claims.d.ts +0 -463
  567. package/dist/transaction/wire/claims.js +0 -229
  568. package/dist/transaction/wire/commit.d.ts +0 -603
  569. package/dist/transaction/wire/commit.js +0 -321
  570. package/dist/transaction/wire/delta.d.ts +0 -250
  571. package/dist/transaction/wire/delta.js +0 -147
  572. package/dist/transaction/wire/errorEnvelope.d.ts +0 -72
  573. package/dist/transaction/wire/errorEnvelope.js +0 -123
  574. package/dist/transaction/wire/feedCursor.d.ts +0 -60
  575. package/dist/transaction/wire/feedCursor.js +0 -82
  576. package/dist/transaction/wire/feedEvent.d.ts +0 -177
  577. package/dist/transaction/wire/feedEvent.js +0 -39
  578. package/dist/transaction/wire/frames.d.ts +0 -194
  579. package/dist/transaction/wire/frames.js +0 -50
  580. package/dist/transaction/wire/inboundFrames.d.ts +0 -552
  581. package/dist/transaction/wire/inboundFrames.js +0 -116
  582. package/dist/transaction/wire/index.d.ts +0 -50
  583. package/dist/transaction/wire/index.js +0 -74
  584. package/dist/transaction/wire/listEnvelope.d.ts +0 -37
  585. package/dist/transaction/wire/listEnvelope.js +0 -42
  586. package/dist/transaction/wire/modelResponses.d.ts +0 -85
  587. package/dist/transaction/wire/modelResponses.js +0 -43
  588. package/dist/transaction/wire/protocol.d.ts +0 -38
  589. package/dist/transaction/wire/protocol.js +0 -38
  590. package/dist/transaction/wire/protocolVersion.d.ts +0 -73
  591. package/dist/transaction/wire/protocolVersion.js +0 -83
  592. package/dist/transactions/mutations/MutationQueue.d.ts +0 -655
  593. package/dist/transactions/mutations/MutationQueue.js +0 -2797
  594. package/dist/transactions/mutations/MutationStore.d.ts +0 -20
  595. package/dist/transactions/mutations/MutationStore.js +0 -53
  596. package/dist/transactions/mutations/UnconfirmedWrites.d.ts +0 -82
  597. package/dist/transactions/mutations/UnconfirmedWrites.js +0 -104
  598. package/dist/transactions/mutations/coalesceRules.d.ts +0 -58
  599. package/dist/transactions/mutations/coalesceRules.js +0 -140
  600. package/dist/transactions/mutations/commitLatency.d.ts +0 -52
  601. package/dist/transactions/mutations/commitLatency.js +0 -130
  602. package/dist/transactions/mutations/commitOutboxStore.d.ts +0 -28
  603. package/dist/transactions/mutations/commitOutboxStore.js +0 -26
  604. package/dist/transactions/mutations/commitPayload.d.ts +0 -164
  605. package/dist/transactions/mutations/commitPayload.js +0 -152
  606. package/dist/transactions/mutations/deltaConfirmation.d.ts +0 -59
  607. package/dist/transactions/mutations/deltaConfirmation.js +0 -233
  608. package/dist/transactions/mutations/durableWriteStore.d.ts +0 -14
  609. package/dist/transactions/mutations/durableWriteStore.js +0 -12
  610. package/dist/transactions/mutations/optimisticApply.d.ts +0 -49
  611. package/dist/transactions/mutations/optimisticApply.js +0 -65
  612. package/dist/transactions/mutations/replayValidation.d.ts +0 -186
  613. package/dist/transactions/mutations/replayValidation.js +0 -163
  614. package/dist/utils/mobxSetup.d.ts +0 -53
  615. package/dist/utils/mobxSetup.js +0 -330
  616. package/dist/webhooks/events.d.ts +0 -43
  617. package/dist/webhooks/events.js +0 -42
  618. package/dist/webhooks/index.d.ts +0 -8
  619. package/dist/webhooks/index.js +0 -8
  620. package/dist/wire/index.d.ts +0 -1
  621. package/dist/wire/index.js +0 -8
  622. package/docs/interaction-model.md +0 -99
package/docs/identity.md CHANGED
@@ -24,9 +24,9 @@ that.
24
24
  A **sync group** is a named channel of shared state — a string like
25
25
  `org:acme` or `workspace:abc123`. It is simultaneously:
26
26
 
27
- - **the unit of fan-out** a confirmed write to a row publishes a delta to
27
+ - **the unit of fan-out:** a confirmed write to a row publishes a delta to
28
28
  every participant subscribed to that row's sync group(s), and
29
- - **the unit of access** a participant receives a row's deltas *only if* the
29
+ - **the unit of access:** a participant receives a row's deltas *only if* the
30
30
  row's sync group is in their allowed set.
31
31
 
32
32
  There is no built-in `org` / `team` / `user` concept in the engine. Those are
@@ -101,16 +101,16 @@ const ablo = Ablo({ schema, apiKey: session.token });
101
101
 
102
102
  That's the whole surface. The rest of this doc is the *why* behind each line.
103
103
 
104
- ## Two kinds of group the whole mental model
104
+ ## Two kinds of group: the whole mental model
105
105
 
106
106
  You just saw a human get `org` / `team` groups and an agent get one `workspace`
107
107
  group. That split is the model. Every sync group is named after one of two
108
108
  things:
109
109
 
110
- - **Membership groups** named after *who you are*: `org:{id}`, `team:{id}`,
110
+ - **Membership groups:** named after *who you are*: `org:{id}`, `team:{id}`,
111
111
  `user:{id}`. Produced from **identity** (`identityRoles`, Half 1). They're
112
112
  standing and durable — they don't change as you work.
113
- - **Entity groups** named after *a thing*: `dataroom:{id}`, `workspace:{id}`,
113
+ - **Entity groups:** named after *a thing*: `dataroom:{id}`, `workspace:{id}`,
114
114
  `document:{id}`. Produced from a **row's id** (a model's entity scope, Half 2).
115
115
  They're granular — one per record — and any participant can be pointed at a
116
116
  specific set of them.
@@ -122,8 +122,8 @@ they are, so you declare them once in the schema.
122
122
 
123
123
  | | Subscribed by | Declared where | Gets |
124
124
  | --- | --- | --- | --- |
125
- | **Human** | *who they are* membership | **the schema** (`identityRoles`) a rule, written once | every `org` / `team` / `user` group their identity implies their whole standing world |
126
- | **Agent** | *what it's been given* entities | **code, at the spawn site** chosen per run | a handful of entity groups: the dataroom it's in, the documents it has read never beyond what its user's membership could reach |
125
+ | **Human** | *who they are*: membership | **the schema** (`identityRoles`): a rule, written once | every `org` / `team` / `user` group their identity implies: their whole standing world |
126
+ | **Agent** | *what it's been given*: entities | **code, at the spawn site**: chosen per run | a handful of entity groups: the dataroom it's in, the documents it has read: never beyond what its user's membership could reach |
127
127
 
128
128
  > **One line:** humans subscribe by who they are; agents subscribe by what
129
129
  > they've been given.
@@ -180,6 +180,7 @@ await mintUserSessionKey({
180
180
  organizationId: schemaOwnerOrgId,
181
181
  projectId: schemaProjectId,
182
182
  },
183
+ operations: ['task.read', 'task.update'],
183
184
  ttlSeconds: 3600,
184
185
  });
185
186
  ```
@@ -197,7 +198,7 @@ Scoping is two declarations that meet in the middle. One describes the
197
198
  (which group does this row belong to?). A participant sees a row **iff** the
198
199
  row's sync group is in the participant's allowed set.
199
200
 
200
- ### Half 1 `identityRoles`: identity → allowed groups
201
+ ### Half 1 (`identityRoles`): identity → allowed groups
201
202
 
202
203
  Declared once, on the schema, via the `identityRole({ kind, source })` factory.
203
204
  Each role is **pure data**: a `kind` (the group's prefix — `org`, `user`, `team`)
@@ -238,7 +239,7 @@ in-process and on a hosted server that only ever sees the compiled JSON.
238
239
  > `user:{id}` role above already covers it — see
239
240
  > [Agents are participants too](#agents-are-participants-too).
240
241
 
241
- ### Half 2 per-model scope: row → group
242
+ ### Half 2 (per-model scope): row → group
242
243
 
243
244
  You never write a sync-group string for a row. You declare a model's *place* in
244
245
  the entity graph and the engine derives the groups its rows fan out on. Three
@@ -308,9 +309,9 @@ exposed the whole table cross-tenant, so `validate_schema` rejects the removed
308
309
  options as `tenancy-option-removed` errors and steers you to `policy: { by:
309
310
  'parent' }` (FK inheritance) or, for genuinely global reference data, the
310
311
  explicit `policy: { by: 'none' }`. See
311
- `packages/sync-engine/src/schema/model.ts` for the full option set.
312
+ `packages/transaction/src/schema/model.ts` for the full option set.
312
313
 
313
- ## How identity reaches Ablo the proxy model
314
+ ## How identity reaches Ablo: the proxy model
314
315
 
315
316
  This is the part the README's "authenticates with the signed-in user's
316
317
  session" glossed over. Concretely:
@@ -400,9 +401,9 @@ What carries identity — and just as importantly, what does *not* set the bound
400
401
 
401
402
  | Where | Purpose |
402
403
  | ------------ | ------------------------------------------------------------------------------------------------ |
403
- | `userId` prop | App-level participant id, used for app-owned fields and read by your `identityRole` `source`. **Not** the security boundary the server enforces scope from the authenticated request. |
404
+ | `userId` prop | App-level participant id, used for app-owned fields and read by your `identityRole` `source`. **Not** the security boundary: the server enforces scope from the authenticated request. |
404
405
  | `teamIds` (on the client) | Team ids expanded into team sync groups via your `identityRoles`. |
405
- | `syncGroups` (at session mint) | Optional. **Narrows** a minted session's subscription to a subset of what auth already allows it can never widen it. Passed to `sessions.create({ user \| agent, syncGroups })`; build entries with `syncGroup(kind, id)`. Use it to scope an agent (or a focused page's session) to one entity, e.g. `[syncGroup('workspace', 'abc123')]`. |
406
+ | `syncGroups` (at session mint) | Optional. **Narrows** a minted session's subscription to a subset of what auth already allows: it can never widen it. Passed to `sessions.create({ user \| agent, syncGroups })`; build entries with `syncGroup(kind, id)`. Use it to scope an agent (or a focused page's session) to one entity, e.g. `[syncGroup('workspace', 'abc123')]`. |
406
407
 
407
408
  Because the server is the boundary, a client that changes `userId` to another
408
409
  user's id does not gain their data — the server resolves and enforces the real
@@ -431,7 +432,7 @@ agent authority = (triggering user's allowed set) ← ceiling, inherited (on-
431
432
  ```
432
433
 
433
434
  Concretely: each model an agent edits declares a `scope`
434
- ([Half 2](#half-2--per-model-scope-row--group)), so each row forms its own
435
+ ([Half 2](#half-2-per-model-scope-row--group)), so each row forms its own
435
436
  group. The agent subscribes only to the groups for the rows it touches. Declare
436
437
  an entity anchor on the models an agent operates on:
437
438
 
@@ -475,22 +476,21 @@ not *what's reachable*.
475
476
  Three rules make agent access safe, and they fall out of the model above rather
476
477
  than needing a separate agent permission system:
477
478
 
478
- - **Inherit the user, and no more** the OAuth
479
+ - **Inherit the user, and no more:** the OAuth
479
480
  [on-behalf-of](https://workos.com/blog/oauth-on-behalf-of-ai-agents) model: the
480
481
  agent's reach is tied to the consenting user, never the org.
481
- - **Least privilege, just-in-time** scoped to the task's entities, not standing
482
+ - **Least privilege, just-in-time:** scoped to the task's entities, not standing
482
483
  org-wide access (the over-privilege pattern
483
484
  [OWASP's NHI Top 10](https://www.token.security/assets/the-ultimate-non-human-identity-security-guide)
484
485
  flags as the dominant agent risk).
485
- - **Dual-principal attribution** record both the executing agent and the
486
+ - **Dual-principal attribution:** record both the executing agent and the
486
487
  triggering human.
487
488
 
488
489
  Identity is 1:1 with a human participant; authority is narrowed to the work. That
489
490
  split is what lets Ablo keep *one model API for every actor* without ever
490
491
  granting an agent standing access to everything its user can see. The agent that
491
- runs the [Coordinating long agent work](../README.md#coordinating-long-agent-work)
492
- `claim` loop is, to the scoping layer, that same participant — scoped to the row
493
- it claimed.
492
+ runs the [Coordination](./coordination.md) `claim` loop is, to the scoping layer,
493
+ that same participant — scoped to the row it claimed.
494
494
 
495
495
  ## Narrowing to specific entities
496
496
 
@@ -530,7 +530,7 @@ an agent pointed at the entities it's working on. You **never hand-write**
530
530
 
531
531
  > **`groups.root` is the schema model option, not a client setting.**
532
532
  > `groups: { root: 'workspace' }` in `model(...)` declares a scope root
533
- > ([Half 2](#half-2--per-model-scope-row--group)) — it names the group
533
+ > ([Half 2](#half-2-per-model-scope-row--group)) — it names the group
534
534
  > (`workspace:<id>`) that the mechanisms above then subscribe to.
535
535
  > There is no `Ablo({ scope })` constructor option. The lifecycle filter on
536
536
  > [`list()`](./api.md#model-methods) is a separate axis named **`state`**
@@ -543,7 +543,7 @@ an agent pointed at the entities it's working on. You **never hand-write**
543
543
  > can't reach a workspace its capability doesn't already permit, no matter what it
544
544
  > passes. Smaller bootstrap, less fan-out, same server-enforced boundary.
545
545
 
546
- ## How this compares and the best practices it follows
546
+ ## How this compares, and the best practices it follows
547
547
 
548
548
  Ablo's identity model is not novel; it's the convergent answer every serious
549
549
  realtime / sync SDK arrived at. Knowing which industry pattern it *is* tells you
@@ -551,7 +551,7 @@ how to reason about it.
551
551
 
552
552
  **Realtime authorization splits into two shapes.** Ablo is firmly in the first:
553
553
 
554
- - **Server derives scope from authenticated identity** the server decides what
554
+ - **Server derives scope from authenticated identity:** the server decides what
555
555
  a participant may read/write and the client cannot override it. This is Ablo's
556
556
  proxy model. It's the same shape as
557
557
  [Supabase Realtime's RLS-on-connect](https://supabase.com/docs/guides/realtime/authorization)
@@ -560,7 +560,7 @@ how to reason about it.
560
560
  checks the permissions for you" — recommended for production), and
561
561
  [ElectricSQL **proxy auth**](https://electric-sql.com/docs/guides/auth) (a
562
562
  reverse-proxy sets shape params server-side before forwarding).
563
- - **Client proposes, server authorizes the exact request** the client names
563
+ - **Client proposes, server authorizes the exact request:** the client names
564
564
  the room/shape and the server signs off, as in
565
565
  [Pusher's channel authorization endpoint](https://pusher.com/docs/channels/server_api/authorizing-users/),
566
566
  [ElectricSQL **gatekeeper auth**](https://github.com/electric-sql/electric/blob/main/examples/gatekeeper-auth/README.md),
package/docs/index.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Ablo Docs
2
2
 
3
- > The agentic coordination layer: one API for AI agents, apps, and services to claim, change, and confirm the same rows.
3
+ > Collaboration infrastructure for AI agents: one API for agents, apps, and services to claim, change, and confirm the same rows.
4
4
 
5
5
  Two agents reach for the same row. One claims it, does slow work — an LLM call,
6
6
  a fetch, a chain of tools — and commits. The second is neither rejected nor
@@ -110,12 +110,12 @@ Every surface reaches the same coordinated state. Pick by who is calling.
110
110
 
111
111
  | Surface | Use it for |
112
112
  |---|---|
113
- | **SDK** `@abloatai/ablo`, `transport: 'http'` | The agents themselves. Stateless, request/response, nothing held open. The main path. |
114
- | **Coordination MCP** `@abloatai/mcp` | An agent living inside an MCP host that needs claim and commit as tools. A data plane. |
115
- | **`humans()`** with `@abloatai/ablo/react` | The interfaces a person watches agent work arrive in: presence, live queries, a local copy. |
116
- | **CLI** `ablo` | Scaffolding, schema push, connecting a database. Terminals and CI. |
117
- | **REST** `/api/v1` | Runtimes with no SDK. |
118
- | **Integration-helper MCP** hosted `/api/mcp` | Teaching a coding assistant the SDK while you build. Docs, lint, and scaffolds only. |
113
+ | **SDK**: `@abloatai/ablo`, `transport: 'http'` | The agents themselves. Stateless, request/response, nothing held open. The main path. |
114
+ | **Coordination MCP**: `@abloatai/mcp` | An agent living inside an MCP host that needs claim and commit as tools. A data plane. |
115
+ | **`humans()`**: with `@abloatai/ablo/react` | The interfaces a person watches agent work arrive in: presence, live queries, a local copy. |
116
+ | **CLI**: `ablo` | Scaffolding, schema push, connecting a database. Terminals and CI. |
117
+ | **REST**: `/api/v1` | Runtimes with no SDK. |
118
+ | **Integration-helper MCP**: hosted `/api/mcp` | Teaching a coding assistant the SDK while you build. Docs, lint, and scaffolds only. |
119
119
 
120
120
  The two MCP servers are not interchangeable. The coordination server changes
121
121
  your data; the integration-helper server serves documentation and has no
@@ -136,6 +136,7 @@ default caller, not a special one.
136
136
 
137
137
  ## Concepts
138
138
 
139
+ - [How Ablo Works](./how-it-works.md) — the mental model in one page: you write through Ablo, it lands in your Postgres, the write-ahead log confirms it. **Read this first.**
139
140
  - [Coordination](./coordination.md) — `claim`, `claim.state`, and `claim.queue`: who holds a row, and who is waiting.
140
141
  - [Concurrency Convention](./concurrency-convention.md) — the governing rule for how concurrent writes resolve.
141
142
  - [Guarantees](./guarantees.md) — what a confirmed write, a stale-write rejection, and a claim each promise.
@@ -144,7 +145,6 @@ default caller, not a special one.
144
145
  - [Agents](./agents.md) — the stateless participant: wake, read, claim, commit, idle.
145
146
  - [Agent Messaging](./agent-messaging.md) — durable handoffs between agents, linked to the claim they discuss.
146
147
  - [Identity & Sync Groups](./identity.md) — who is connecting, and which slice of state they see.
147
- - [Interaction Model](./interaction-model.md) — the schema, claim, update, confirmation loop.
148
148
  - [Change Propagation](./groups.md) — how one row's change reaches the actors that depend on it.
149
149
  - [Client Behavior](./client-behavior.md) — options, errors, retries, timeouts, and imports.
150
150
 
@@ -11,7 +11,7 @@ backend and a database, one model at a time.
11
11
 
12
12
  Three things hold no matter which actor is writing:
13
13
 
14
- - **One model API for every actor.** `ablo.<model>.update(...)` is what
14
+ - **One model API for every actor:** `ablo.<model>.update(...)` is what
15
15
  React components, server actions, background workers, and AI agents
16
16
  all call. No separate "agent SDK," no parallel mutation path. The
17
17
  attribution comes from the credential, not the call site.
@@ -30,6 +30,7 @@ The normal integration is one client:
30
30
 
31
31
  ```ts
32
32
  import Ablo from '@abloatai/ablo';
33
+ import { credentialEndpointSuccessSchema } from '@abloatai/ablo/auth';
33
34
  import { defineSchema, model, z } from '@abloatai/ablo/schema';
34
35
  ```
35
36
 
@@ -158,7 +159,7 @@ For rows that don't carry `organization_id` themselves but inherit tenancy via a
158
159
  foreign key, set `policy: { by: 'parent', fk: '<fk>', parent: '<parentTable>' }`.
159
160
  For genuinely global/reference data, `policy: { by: 'none' }`. ⚠ `by: 'none'`
160
161
  exposes the whole table cross-tenant, so it's an explicit, named branch — never a
161
- falsy flag. See `packages/sync-engine/src/schema/model.ts` for the full option set.
162
+ falsy flag. See `packages/transaction/src/schema/model.ts` for the full option set.
162
163
 
163
164
  ## 2. Create The Client
164
165
 
@@ -220,8 +221,18 @@ const sync = Ablo({ schema, apiKey: process.env.ABLO_API_KEY });
220
221
 
221
222
  export async function POST() {
222
223
  const session = await auth(); // your own auth — returns the signed-in user
223
- const { token } = await sync.sessions.create({ user: { id: session.userId } });
224
- return Response.json({ token });
224
+ const { token, expiresAt } = await sync.sessions.create({
225
+ user: { id: session.userId },
226
+ can: { tasks: ['read', 'update'] },
227
+ });
228
+ return Response.json(
229
+ credentialEndpointSuccessSchema.parse({
230
+ token,
231
+ expiresAt,
232
+ credentialKind: 'ephemeral',
233
+ }),
234
+ { headers: { 'Cache-Control': 'no-store' } },
235
+ );
225
236
  }
226
237
  ```
227
238
 
@@ -255,8 +266,8 @@ refreshes before expiry.
255
266
  ## 3. Read State
256
267
 
257
268
  Reads come in two flavors, and you pick based on whether you can wait.
258
- `retrieve({ id })` and `list({ where })` hit the server (and hydrate the local
259
- store) — they're async, so you `await` them. `get(id)` (positional),
269
+ `get({ id })` and `list({ where })` hit the server (and hydrate the local
270
+ store) — they're async, so you `await` them. `local.get(id)`,
260
271
  `local.list({ where })`, and `local.count({ where })` read the already-synced local
261
272
  graph synchronously, so they're the ones you call in render — and the ones you
262
273
  use inside a `useAblo` selector, never the async `retrieve`/`list`.
@@ -267,15 +278,15 @@ and waits.
267
278
  ```ts
268
279
  await ablo.ready();
269
280
 
270
- const report = await ablo.weatherReports.retrieve({ id: 'report_stockholm' });
281
+ const report = await ablo.weatherReports.get({ id: 'report_stockholm' });
271
282
  if (!report) throw new Error('report not found');
272
283
  ```
273
284
 
274
- Use `local.retrieve`, `local.list`, and `local.count` for synchronous local-graph reads after
285
+ Use `local.get`, `local.list`, and `local.count` for synchronous local-graph reads after
275
286
  data has synced.
276
287
 
277
288
  ```ts
278
- const report = ablo.weatherReports.local.retrieve('report_stockholm');
289
+ const report = ablo.weatherReports.local.get('report_stockholm');
279
290
  const activeReports = ablo.weatherReports.local.list({
280
291
  where: { projectId: 'proj_123' },
281
292
  filter: (report) => report.status !== 'ready',
@@ -296,7 +307,7 @@ export function ReportRow({
296
307
  }: {
297
308
  report: { id: string; location: string; status: string };
298
309
  }) {
299
- const report = useAblo((ablo) => ablo.weatherReports.local.retrieve(serverReport.id)) ?? serverReport;
310
+ const report = useAblo((ablo) => ablo.weatherReports.local.get(serverReport.id)) ?? serverReport;
300
311
  const active = useAblo((ablo) => ablo.weatherReports.claim.state({ id: serverReport.id }));
301
312
 
302
313
  return <button disabled={Boolean(active) || report.status === 'ready'}>{report.location}</button>;
@@ -351,8 +362,19 @@ server -> ablo.weatherReports.update(...)
351
362
  Ablo coordinates those writes, fans out confirmed deltas, exposes active claims,
352
363
  and lets callers reject stale writes with `readAt`.
353
364
 
354
- Direct writes to your own database bypass that stream until your app reports the
355
- change through Data Source events.
365
+ A write that reaches your database some other way still reaches connected
366
+ clients. A `psql` session, a cron job, an admin tool, a legacy endpoint: Ablo
367
+ tails your write-ahead log, so a change it did not make is picked up and fanned
368
+ out like any other, attributed to the data source rather than to an agent.
369
+
370
+ What such a write does not get is the coordination. It never entered the commit
371
+ chokepoint, so no claim was checked, no `readAt` was compared, and no idempotency
372
+ key was honoured. It can land on top of a row an agent is holding. Route anything
373
+ that must respect a claim through `ablo.<model>`.
374
+
375
+ On the [Data Source endpoint fallback](./data-sources.md) there is no replication
376
+ stream to tail, and there the original caveat holds: a direct write stays
377
+ invisible until your app reports it through Data Source events.
356
378
 
357
379
  ## 6. Existing API Backend
358
380
 
@@ -376,7 +398,7 @@ The migration can be gradual:
376
398
 
377
399
  1. Declare schema for one model, such as `reports`.
378
400
  2. Keep existing server loads for first paint.
379
- 3. Add `useAblo((ablo) => ablo.weatherReports.local.retrieve(id)) ?? serverReport` for live rows.
401
+ 3. Add `useAblo((ablo) => ablo.weatherReports.local.get(id)) ?? serverReport` for live rows.
380
402
  4. Add one Data Source endpoint that calls the existing service layer.
381
403
  5. Move one mutation button from `fetch('/api/reports/...')` to `ablo.weatherReports.update(...)`.
382
404
  6. Add an outbox/events path for writes that still happen outside Ablo.
@@ -505,9 +527,9 @@ them.
505
527
 
506
528
  | Method | Use it for |
507
529
  | -------------------------------------- | -------------------------------------------------------------------------------- |
508
- | `retrieve({ id })` | Async read of one row from the server (await it). |
530
+ | `get({ id })` | Async read of one row from the server (await it). |
509
531
  | `list({ where })` | Async read of many rows from the server (await it). |
510
- | `get(id)` | Synchronous local read of one synced row (positional id; use in render). |
532
+ | `local.get(id)` | Synchronous local read of one synced row (use in render). |
511
533
  | `local.list({ where })` | Synchronous local read of many synced rows. |
512
534
  | `local.count({ where })` | Synchronous local count of synced rows. |
513
535
  | `create({ data, id? })` | Create through the model client. |
@@ -517,5 +539,5 @@ them.
517
539
  | `claim({ id, description?, ttl? })` | Acquire a disposable handle: wait for your turn, re-read, and hold the row. |
518
540
 
519
541
  Keep first integrations on the model methods above. Every mutation and
520
- server-read verb takes one options object; only the synchronous `get(id)` stays
542
+ server-read verb takes one options object; the synchronous `local.get(id)` stays
521
543
  positional.
@@ -0,0 +1,18 @@
1
+ # Internal Architecture Notes
2
+
3
+ These documents explain implementation and protocol decisions for contributors.
4
+ They are not extra public import paths.
5
+
6
+ The ownership rule is:
7
+
8
+ - transaction owns transport-neutral and HTTP contracts;
9
+ - humans owns reactive state, WebSockets, presence, browser persistence, and React;
10
+ - agent owns agent-specific behavior and perception;
11
+ - the branded `@abloatai/ablo` package maps stable public entrypoints to those
12
+ owners;
13
+ - `apps/sync-server` owns backend execution.
14
+
15
+ Consumer code should import `@abloatai/ablo` and its documented subpaths.
16
+ Contributor code should import the narrow owner package or module it actually
17
+ uses. Do not add forwarding compatibility packages or duplicate contract
18
+ definitions.
@@ -0,0 +1,171 @@
1
+ # Coordination as Eyes and Ears for Agent Fleets
2
+
3
+ The design intent behind claims, presence, and stale-context — stated as one
4
+ picture so it can be argued about and built against, not re-derived each time
5
+ someone asks "how do the coordination agents work?"
6
+
7
+ ## The thesis
8
+
9
+ Humans coordinating in a shared document already have everything they need:
10
+ they *see* each other's cursors, they *hover* to highlight the region they're
11
+ touching, and they *say* what they're doing ("I'm rewriting the intro"). Nobody
12
+ overwrites anybody because everybody has eyes and ears.
13
+
14
+ Agents don't. They work directly and silently, at machine speed, in fleets — say
15
+ 100 agents across 10 groups, each group on its own area of the data. The
16
+ coordination layer's job is to give that fleet the same social awareness a room
17
+ of humans has, expressed as a protocol: **see who is working where, learn what
18
+ they are doing, and take a turn instead of a collision.**
19
+
20
+ At fleet scale the load-bearing property is that this stays *local*. The layer
21
+ does not lock "the fleet." It coordinates per row. 100 agents over 10
22
+ non-overlapping areas are 100 parallel tracks that only ever meet on the
23
+ handful of rows two agents genuinely both want. Cost is paid at the overlap, not
24
+ across the fleet — which is why adding agents on separate areas adds no
25
+ coordination cost.
26
+
27
+ ## The one principle: two channels, never crossed
28
+
29
+ Awareness and safety are different channels, and keeping them apart is what makes
30
+ this safe *and* loop-free at machine speed.
31
+
32
+ - **Safety is pull, at write time.** An agent acts on its best read and its write
33
+ is rejected if the row moved underneath it. The rejection is the signal, and it
34
+ only ever fires when an agent actually chooses to write. A pull channel cannot
35
+ loop — nothing is being pushed.
36
+ - **Awareness is push, and it is the only channel that can storm.** So it is the
37
+ only channel we coalesce and rate-limit. Hot data that changes every
38
+ millisecond lives entirely on the safe *pull* side and therefore generates zero
39
+ awareness traffic — an agent that cares about a fast-ticking value just tries
40
+ its write and re-reads if it lost, rather than being woken on every tick.
41
+
42
+ Collapse the two channels — "notify every reader on every change" — and a
43
+ millisecond-ticking field produces read → notify → re-read → act → notify →
44
+ forever. Keeping them separate is the whole reason that loop can't form.
45
+
46
+ ## The six behaviors
47
+
48
+ ### 1. Eyes: see who is working where
49
+
50
+ Presence broadcasts, live, which agent holds which row. Before an agent commits
51
+ to work, it can see the area is already taken. This is advisory: it informs, it
52
+ forces nothing.
53
+
54
+ ```ts
55
+ const who = ablo.tasks.claim.state({ id: 'task_123' }); // holder or null
56
+ // who.heldBy === 'agent:forecaster'
57
+ // who.description === 'rewriting the risk section to match Q3'
58
+ ```
59
+
60
+ ### 2. Ears: learn *what* they are doing
61
+
62
+ A claim carries a single `description` — the machine version of the
63
+ hover-highlight plus the spoken "what I'm doing," in one field. It is the
64
+ sentence a peer reads to decide whether to wait, work elsewhere, or move on. It
65
+ defaults to `'editing'` when a claim is taken without one.
66
+
67
+ ```ts
68
+ await using claim = await ablo.tasks.claim({
69
+ id: 'task_123',
70
+ description: 'rewriting the risk section to match Q3 numbers',
71
+ });
72
+ ```
73
+
74
+ ### 3. Reject *before* the tokens are spent
75
+
76
+ The claim is a **cheap pre-flight, taken before the generation, not before the
77
+ write.** A human wastes nothing by starting to type into a locked paragraph; an
78
+ agent wastes a whole expensive completion. So the discipline is:
79
+
80
+ ```txt
81
+ claim (cheap) -> if granted: generate the block -> write
82
+ \-> if held: never generate anything
83
+ ```
84
+
85
+ An agent that is told "no" at the claim never produced the write that would have
86
+ lost — the large token spend simply did not happen. This is the single most
87
+ important reason the claim exists before the work, not after it.
88
+
89
+ ### 4. Reject *with* the description, so the blocked agent can decide
90
+
91
+ A bare "taken" forces a blind retry. The rejection carries the holder's
92
+ `description`, and the SDK renders it into the `AbloClaimedError` message:
93
+ *"Claimed by agent:forecaster: rewriting the risk section to match Q3."* So the
94
+ blocked agent reasons on real information: wait for the turn, go work somewhere
95
+ else, or drop the task because the work is already being done. "No, because
96
+ someone is rewriting the risk section" is actionable in a way "no" is not.
97
+
98
+ ### 5. Queue: take a turn, with an opt-out if the line is long
99
+
100
+ Contention is a fair FIFO queue: the blocked agent waits its turn and is
101
+ *notified* the moment it arrives (push, not poll — it does not sit and spin).
102
+ When promoted, it re-reads so it works from the latest, with the previous
103
+ holder's change already in place. And the queue has an opt-out: past a depth
104
+ bound, an agent is told the area is too busy and moves on rather than joining a
105
+ long line.
106
+
107
+ ```ts
108
+ await using claim = await ablo.tasks.claim({
109
+ id: 'task_123',
110
+ description: '...',
111
+ maxQueueDepth: 3, // don't join a line deeper than this
112
+ });
113
+ ```
114
+
115
+ ### 6. Notify on change: without acting on stale data, without looping
116
+
117
+ An agent that read a row and is about to act on it is stopped if the row moved
118
+ since the read; it re-reads instead of acting stale. Where a genuine
119
+ notification is wanted, it is **coalesced** (one settled signal, not a stream)
120
+ and **relevance-gated** (only the fields a decision depends on can wake the
121
+ agent). A fast-ticking value never wakes anyone; a rarely-changing value that
122
+ matters can push one settled signal. Same primitive, two behaviors, chosen by
123
+ whether reacting is worth it — see the two-channel principle above.
124
+
125
+ ## The three layers, as a rising scale
126
+
127
+ The behaviors above compose into three layers of increasing firmness. An agent
128
+ climbs only as high as the situation needs.
129
+
130
+ | Layer | Kind | What it does | Forces anything? |
131
+ | --- | --- | --- | --- |
132
+ | **Presence** | awareness (push) | Shows who holds what, and why, live. | No: informs only. |
133
+ | **Stale-context** | safety (pull) | Rejects a write built on a read the row has moved past. | Yes: at write time. |
134
+ | **Claim + queue** | reservation (push) | Reserves a row across a slow gap; contenders take turns. | Yes: mutual exclusion. |
135
+
136
+ Most work is a quick write and needs only the safety layer. An agent reaches for
137
+ a claim only when it will *hold* a row across a slow gap (read → LLM → write) —
138
+ the case where taking a turn beats colliding.
139
+
140
+ ## What's shipped, and the one open point
141
+
142
+ One piece of the fleet story that once read as future design work is already
143
+ built; one is genuinely still open. Both are called out so neither is misjudged.
144
+
145
+ 1. **Rich work surfaced at reject time — shipped.** A claim carries a single
146
+ `description` (behavior 2) as a first-class field on the wire. It rides the
147
+ presence broadcast, comes back inside the rejection's holder summary
148
+ (`heldByClaim`), and the SDK's `formatClaimedErrorMessage` renders it into the
149
+ `AbloClaimedError`. So "no" already becomes "no, because someone is rewriting
150
+ the risk section" (behavior 4) — the piece that prevents the wasteful blind
151
+ retry works today.
152
+
153
+ 2. **Coalesced, relevance-gated notify — open.** The anti-loop guarantee
154
+ (behavior 6) depends on the awareness channel being coalesced and gated by
155
+ relevance, and on hot data staying on the pull side. This is the sharp one,
156
+ and it is the one not yet built: what exists is the write-time pull guard
157
+ (`onStale`) and operation-level batching, not a coalesced, relevance-gated
158
+ *push* on the presence broadcast. Get it wrong and a millisecond-ticking field
159
+ storms the fleet. The rule to hold: an agent is *rejected at write time* on
160
+ hot data, never *subscribed-and-woken* by it.
161
+
162
+ ## Related
163
+
164
+ - [`coordination.md`](../coordination.md) — the public claim/queue/stale-context
165
+ reference this note motivates.
166
+ - [`agent-orchestration.md`](./agent-orchestration.md) — parent/child agent work
167
+ modeled through claimed job rows; this note is the coordination substrate under
168
+ it.
169
+ - ADR 0009 (`docs/decisions/0009-claim-durability-two-reclaim-clocks.md`) — what a
170
+ claim survives when a holder vanishes, and why liveness can be best-effort while
171
+ correctness is fenced at commit.
@@ -0,0 +1,58 @@
1
+ # Agent Orchestration
2
+
3
+ Do not model parent and child agents as directly talking to each other over WebSocket.
4
+
5
+ Model them as actors coordinating through models:
6
+
7
+ ```txt
8
+ parent creates job -> child claims job -> child commits result -> parent reads result
9
+ ```
10
+
11
+ The WebSocket is delivery infrastructure. The product model is shared state.
12
+
13
+ ## Model Shape
14
+
15
+ A parent creates a job through its typed model client:
16
+
17
+ ```ts
18
+ const jobId = `forecast:${runId}`;
19
+ await ablo.agentJobs.create({
20
+ id: jobId,
21
+ idempotencyKey: `job:${runId}`,
22
+ data: {
23
+ status: 'open',
24
+ kind: 'forecast_report',
25
+ target: { model: 'weatherReports', id: 'report_stockholm', field: 'forecast' },
26
+ },
27
+ wait: 'confirmed',
28
+ });
29
+ ```
30
+
31
+ The child claims the job. If another worker holds it, the claim waits fairly,
32
+ then returns the fresh row:
33
+
34
+ ```ts
35
+ await using claim = await ablo.agentJobs.claim({
36
+ id: jobId,
37
+ description: 'complete',
38
+ ttl: '5m',
39
+ });
40
+ const job = claim.data;
41
+
42
+ await ablo.agentJobs.update({
43
+ id: job.id,
44
+ data: {
45
+ status: 'completed',
46
+ result: { text },
47
+ },
48
+ });
49
+ ```
50
+
51
+ The child commits completion through the normal `update`, which is stale-guarded
52
+ under the held claim. The claim releases when its scope exits.
53
+
54
+ The parent retrieves the job result by model ID. Later, `ablo.events` can make that reactive, but the state model does not change.
55
+
56
+ ## Rule
57
+
58
+ Nested agents should create or complete models. They should not require a separate agent-to-agent protocol for normal work.