@fuzdev/fuz_app 0.55.0 → 0.57.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 (333) hide show
  1. package/dist/actions/CLAUDE.md +211 -155
  2. package/dist/actions/action_bridge.d.ts +8 -5
  3. package/dist/actions/action_bridge.d.ts.map +1 -1
  4. package/dist/actions/action_bridge.js +1 -11
  5. package/dist/actions/action_codegen.d.ts +19 -0
  6. package/dist/actions/action_codegen.d.ts.map +1 -1
  7. package/dist/actions/action_codegen.js +20 -14
  8. package/dist/actions/action_registry.d.ts.map +1 -1
  9. package/dist/actions/action_registry.js +5 -2
  10. package/dist/actions/action_rpc.d.ts +110 -44
  11. package/dist/actions/action_rpc.d.ts.map +1 -1
  12. package/dist/actions/action_rpc.js +92 -287
  13. package/dist/actions/action_spec.d.ts +55 -16
  14. package/dist/actions/action_spec.d.ts.map +1 -1
  15. package/dist/actions/action_spec.js +16 -11
  16. package/dist/actions/action_types.d.ts +28 -60
  17. package/dist/actions/action_types.d.ts.map +1 -1
  18. package/dist/actions/action_types.js +13 -5
  19. package/dist/actions/broadcast_api.d.ts +2 -2
  20. package/dist/actions/broadcast_api.js +2 -2
  21. package/dist/actions/compile_action_registry.d.ts +50 -0
  22. package/dist/actions/compile_action_registry.d.ts.map +1 -0
  23. package/dist/actions/compile_action_registry.js +69 -0
  24. package/dist/actions/heartbeat.d.ts +8 -4
  25. package/dist/actions/heartbeat.d.ts.map +1 -1
  26. package/dist/actions/heartbeat.js +5 -4
  27. package/dist/actions/perform_action.d.ts +145 -0
  28. package/dist/actions/perform_action.d.ts.map +1 -0
  29. package/dist/actions/perform_action.js +258 -0
  30. package/dist/actions/register_action_ws.d.ts +44 -38
  31. package/dist/actions/register_action_ws.d.ts.map +1 -1
  32. package/dist/actions/register_action_ws.js +101 -159
  33. package/dist/actions/register_ws_endpoint.d.ts +2 -10
  34. package/dist/actions/register_ws_endpoint.d.ts.map +1 -1
  35. package/dist/actions/register_ws_endpoint.js +32 -10
  36. package/dist/actions/transports_ws_auth_guard.d.ts +1 -1
  37. package/dist/actions/transports_ws_auth_guard.js +1 -1
  38. package/dist/actions/transports_ws_backend.d.ts +1 -1
  39. package/dist/actions/transports_ws_backend.js +1 -1
  40. package/dist/auth/CLAUDE.md +673 -442
  41. package/dist/auth/account_action_specs.d.ts +28 -7
  42. package/dist/auth/account_action_specs.d.ts.map +1 -1
  43. package/dist/auth/account_action_specs.js +7 -7
  44. package/dist/auth/account_actions.d.ts +8 -14
  45. package/dist/auth/account_actions.d.ts.map +1 -1
  46. package/dist/auth/account_actions.js +26 -32
  47. package/dist/auth/account_queries.d.ts +46 -13
  48. package/dist/auth/account_queries.d.ts.map +1 -1
  49. package/dist/auth/account_queries.js +73 -33
  50. package/dist/auth/account_routes.d.ts +4 -3
  51. package/dist/auth/account_routes.d.ts.map +1 -1
  52. package/dist/auth/account_routes.js +58 -33
  53. package/dist/auth/account_schema.d.ts +46 -54
  54. package/dist/auth/account_schema.d.ts.map +1 -1
  55. package/dist/auth/account_schema.js +21 -48
  56. package/dist/auth/admin_action_specs.d.ts +55 -21
  57. package/dist/auth/admin_action_specs.d.ts.map +1 -1
  58. package/dist/auth/admin_action_specs.js +42 -26
  59. package/dist/auth/admin_actions.d.ts +14 -21
  60. package/dist/auth/admin_actions.d.ts.map +1 -1
  61. package/dist/auth/admin_actions.js +47 -44
  62. package/dist/auth/audit_emitter.d.ts +160 -0
  63. package/dist/auth/audit_emitter.d.ts.map +1 -0
  64. package/dist/auth/audit_emitter.js +83 -0
  65. package/dist/auth/audit_log_queries.d.ts +17 -87
  66. package/dist/auth/audit_log_queries.d.ts.map +1 -1
  67. package/dist/auth/audit_log_queries.js +17 -96
  68. package/dist/auth/audit_log_routes.d.ts +1 -1
  69. package/dist/auth/audit_log_routes.d.ts.map +1 -1
  70. package/dist/auth/audit_log_routes.js +7 -3
  71. package/dist/auth/audit_log_schema.d.ts +48 -42
  72. package/dist/auth/audit_log_schema.d.ts.map +1 -1
  73. package/dist/auth/audit_log_schema.js +56 -43
  74. package/dist/auth/auth_guard_resolver.d.ts +44 -0
  75. package/dist/auth/auth_guard_resolver.d.ts.map +1 -0
  76. package/dist/auth/auth_guard_resolver.js +56 -0
  77. package/dist/auth/bootstrap_account.d.ts +7 -7
  78. package/dist/auth/bootstrap_account.d.ts.map +1 -1
  79. package/dist/auth/bootstrap_account.js +7 -7
  80. package/dist/auth/bootstrap_routes.d.ts.map +1 -1
  81. package/dist/auth/bootstrap_routes.js +11 -10
  82. package/dist/auth/cleanup.d.ts +20 -26
  83. package/dist/auth/cleanup.d.ts.map +1 -1
  84. package/dist/auth/cleanup.js +33 -47
  85. package/dist/auth/credential_type_schema.d.ts +115 -0
  86. package/dist/auth/credential_type_schema.d.ts.map +1 -0
  87. package/dist/auth/credential_type_schema.js +127 -0
  88. package/dist/auth/daemon_token_middleware.d.ts +1 -1
  89. package/dist/auth/daemon_token_middleware.js +3 -3
  90. package/dist/auth/ddl.d.ts +2 -2
  91. package/dist/auth/ddl.d.ts.map +1 -1
  92. package/dist/auth/ddl.js +6 -6
  93. package/dist/auth/deps.d.ts +7 -32
  94. package/dist/auth/deps.d.ts.map +1 -1
  95. package/dist/auth/grant_path_schema.d.ts +117 -0
  96. package/dist/auth/grant_path_schema.d.ts.map +1 -0
  97. package/dist/auth/grant_path_schema.js +137 -0
  98. package/dist/auth/invite_queries.d.ts +12 -1
  99. package/dist/auth/invite_queries.d.ts.map +1 -1
  100. package/dist/auth/invite_queries.js +12 -1
  101. package/dist/auth/invite_schema.d.ts +1 -1
  102. package/dist/auth/invite_schema.d.ts.map +1 -1
  103. package/dist/auth/invite_schema.js +1 -1
  104. package/dist/auth/middleware.d.ts.map +1 -1
  105. package/dist/auth/middleware.js +5 -2
  106. package/dist/auth/migrations.d.ts +22 -7
  107. package/dist/auth/migrations.d.ts.map +1 -1
  108. package/dist/auth/migrations.js +64 -25
  109. package/dist/auth/request_context.d.ts +157 -170
  110. package/dist/auth/request_context.d.ts.map +1 -1
  111. package/dist/auth/request_context.js +224 -268
  112. package/dist/auth/{permit_offer_action_specs.d.ts → role_grant_offer_action_specs.d.ts} +130 -100
  113. package/dist/auth/role_grant_offer_action_specs.d.ts.map +1 -0
  114. package/dist/auth/role_grant_offer_action_specs.js +262 -0
  115. package/dist/auth/role_grant_offer_actions.d.ts +104 -0
  116. package/dist/auth/role_grant_offer_actions.d.ts.map +1 -0
  117. package/dist/auth/{permit_offer_actions.js → role_grant_offer_actions.js} +153 -140
  118. package/dist/auth/{permit_offer_notifications.d.ts → role_grant_offer_notifications.d.ts} +80 -70
  119. package/dist/auth/role_grant_offer_notifications.d.ts.map +1 -0
  120. package/dist/auth/role_grant_offer_notifications.js +182 -0
  121. package/dist/auth/{permit_offer_queries.d.ts → role_grant_offer_queries.d.ts} +64 -64
  122. package/dist/auth/role_grant_offer_queries.d.ts.map +1 -0
  123. package/dist/auth/{permit_offer_queries.js → role_grant_offer_queries.js} +136 -123
  124. package/dist/auth/role_grant_offer_schema.d.ts +150 -0
  125. package/dist/auth/role_grant_offer_schema.d.ts.map +1 -0
  126. package/dist/auth/{permit_offer_schema.js → role_grant_offer_schema.js} +55 -36
  127. package/dist/auth/role_grant_queries.d.ts +231 -0
  128. package/dist/auth/role_grant_queries.d.ts.map +1 -0
  129. package/dist/auth/role_grant_queries.js +320 -0
  130. package/dist/auth/role_schema.d.ts +150 -40
  131. package/dist/auth/role_schema.d.ts.map +1 -1
  132. package/dist/auth/role_schema.js +144 -45
  133. package/dist/auth/scope_kind_schema.d.ts +96 -0
  134. package/dist/auth/scope_kind_schema.d.ts.map +1 -0
  135. package/dist/auth/scope_kind_schema.js +94 -0
  136. package/dist/auth/self_service_role_action_specs.d.ts +4 -1
  137. package/dist/auth/self_service_role_action_specs.d.ts.map +1 -1
  138. package/dist/auth/self_service_role_action_specs.js +2 -2
  139. package/dist/auth/self_service_role_actions.d.ts +35 -29
  140. package/dist/auth/self_service_role_actions.d.ts.map +1 -1
  141. package/dist/auth/self_service_role_actions.js +58 -48
  142. package/dist/auth/session_cookie.d.ts +43 -6
  143. package/dist/auth/session_cookie.d.ts.map +1 -1
  144. package/dist/auth/session_cookie.js +31 -5
  145. package/dist/auth/session_middleware.d.ts +37 -3
  146. package/dist/auth/session_middleware.d.ts.map +1 -1
  147. package/dist/auth/session_middleware.js +33 -7
  148. package/dist/auth/signup_routes.d.ts.map +1 -1
  149. package/dist/auth/signup_routes.js +48 -19
  150. package/dist/auth/standard_action_specs.d.ts +2 -2
  151. package/dist/auth/standard_action_specs.js +4 -4
  152. package/dist/auth/standard_rpc_actions.d.ts +23 -19
  153. package/dist/auth/standard_rpc_actions.d.ts.map +1 -1
  154. package/dist/auth/standard_rpc_actions.js +12 -12
  155. package/dist/db/migrate.d.ts +1 -1
  156. package/dist/db/migrate.js +1 -1
  157. package/dist/dev/setup.d.ts +2 -2
  158. package/dist/dev/setup.d.ts.map +1 -1
  159. package/dist/dev/setup.js +4 -4
  160. package/dist/env/load.d.ts +1 -1
  161. package/dist/env/load.js +1 -1
  162. package/dist/hono_context.d.ts +27 -45
  163. package/dist/hono_context.d.ts.map +1 -1
  164. package/dist/hono_context.js +14 -28
  165. package/dist/http/CLAUDE.md +235 -121
  166. package/dist/http/auth_shape.d.ts +191 -0
  167. package/dist/http/auth_shape.d.ts.map +1 -0
  168. package/dist/http/auth_shape.js +237 -0
  169. package/dist/http/common_routes.js +3 -3
  170. package/dist/http/db_routes.d.ts +4 -0
  171. package/dist/http/db_routes.d.ts.map +1 -1
  172. package/dist/http/db_routes.js +44 -7
  173. package/dist/http/error_schemas.d.ts +72 -39
  174. package/dist/http/error_schemas.d.ts.map +1 -1
  175. package/dist/http/error_schemas.js +81 -33
  176. package/dist/http/pending_effects.d.ts +71 -18
  177. package/dist/http/pending_effects.d.ts.map +1 -1
  178. package/dist/http/pending_effects.js +87 -18
  179. package/dist/http/proxy.d.ts +52 -5
  180. package/dist/http/proxy.d.ts.map +1 -1
  181. package/dist/http/proxy.js +92 -14
  182. package/dist/http/route_spec.d.ts +89 -75
  183. package/dist/http/route_spec.d.ts.map +1 -1
  184. package/dist/http/route_spec.js +54 -72
  185. package/dist/http/schema_helpers.d.ts +3 -14
  186. package/dist/http/schema_helpers.d.ts.map +1 -1
  187. package/dist/http/schema_helpers.js +2 -14
  188. package/dist/http/surface.d.ts +2 -10
  189. package/dist/http/surface.d.ts.map +1 -1
  190. package/dist/http/surface.js +3 -4
  191. package/dist/http/surface_query.d.ts +39 -35
  192. package/dist/http/surface_query.d.ts.map +1 -1
  193. package/dist/http/surface_query.js +79 -36
  194. package/dist/primitive_schemas.d.ts +39 -0
  195. package/dist/primitive_schemas.d.ts.map +1 -0
  196. package/dist/primitive_schemas.js +40 -0
  197. package/dist/realtime/sse_auth_guard.d.ts +5 -5
  198. package/dist/realtime/sse_auth_guard.js +9 -9
  199. package/dist/runtime/mock.d.ts +1 -1
  200. package/dist/runtime/mock.js +1 -1
  201. package/dist/server/app_backend.d.ts +14 -11
  202. package/dist/server/app_backend.d.ts.map +1 -1
  203. package/dist/server/app_backend.js +12 -8
  204. package/dist/server/app_server.d.ts +7 -7
  205. package/dist/server/app_server.d.ts.map +1 -1
  206. package/dist/server/app_server.js +35 -40
  207. package/dist/server/validate_nginx.d.ts +1 -1
  208. package/dist/server/validate_nginx.js +1 -1
  209. package/dist/testing/CLAUDE.md +50 -38
  210. package/dist/testing/admin_integration.d.ts +5 -6
  211. package/dist/testing/admin_integration.d.ts.map +1 -1
  212. package/dist/testing/admin_integration.js +87 -85
  213. package/dist/testing/app_server.d.ts +11 -14
  214. package/dist/testing/app_server.d.ts.map +1 -1
  215. package/dist/testing/app_server.js +16 -15
  216. package/dist/testing/assertions.d.ts.map +1 -1
  217. package/dist/testing/assertions.js +2 -1
  218. package/dist/testing/attack_surface.d.ts.map +1 -1
  219. package/dist/testing/attack_surface.js +15 -9
  220. package/dist/testing/audit_completeness.d.ts +2 -2
  221. package/dist/testing/audit_completeness.d.ts.map +1 -1
  222. package/dist/testing/audit_completeness.js +36 -36
  223. package/dist/testing/auth_apps.d.ts +5 -4
  224. package/dist/testing/auth_apps.d.ts.map +1 -1
  225. package/dist/testing/auth_apps.js +22 -19
  226. package/dist/testing/data_exposure.d.ts.map +1 -1
  227. package/dist/testing/data_exposure.js +5 -5
  228. package/dist/testing/db.d.ts +1 -1
  229. package/dist/testing/db.d.ts.map +1 -1
  230. package/dist/testing/db.js +4 -4
  231. package/dist/testing/db_entities.d.ts +22 -0
  232. package/dist/testing/db_entities.d.ts.map +1 -0
  233. package/dist/testing/db_entities.js +28 -0
  234. package/dist/testing/entities.d.ts +8 -7
  235. package/dist/testing/entities.d.ts.map +1 -1
  236. package/dist/testing/entities.js +21 -18
  237. package/dist/testing/integration.d.ts.map +1 -1
  238. package/dist/testing/integration.js +13 -14
  239. package/dist/testing/integration_helpers.d.ts +4 -4
  240. package/dist/testing/integration_helpers.d.ts.map +1 -1
  241. package/dist/testing/integration_helpers.js +20 -18
  242. package/dist/testing/middleware.d.ts +4 -4
  243. package/dist/testing/middleware.d.ts.map +1 -1
  244. package/dist/testing/middleware.js +12 -11
  245. package/dist/testing/rpc_attack_surface.d.ts.map +1 -1
  246. package/dist/testing/rpc_attack_surface.js +40 -24
  247. package/dist/testing/rpc_round_trip.d.ts +1 -1
  248. package/dist/testing/rpc_round_trip.d.ts.map +1 -1
  249. package/dist/testing/rpc_round_trip.js +14 -13
  250. package/dist/testing/sse_round_trip.d.ts +3 -4
  251. package/dist/testing/sse_round_trip.d.ts.map +1 -1
  252. package/dist/testing/sse_round_trip.js +7 -11
  253. package/dist/testing/standard.d.ts +1 -1
  254. package/dist/testing/stubs.d.ts +25 -0
  255. package/dist/testing/stubs.d.ts.map +1 -1
  256. package/dist/testing/stubs.js +43 -2
  257. package/dist/testing/surface_invariants.d.ts +14 -6
  258. package/dist/testing/surface_invariants.d.ts.map +1 -1
  259. package/dist/testing/surface_invariants.js +119 -43
  260. package/dist/testing/ws_round_trip.d.ts +12 -13
  261. package/dist/testing/ws_round_trip.d.ts.map +1 -1
  262. package/dist/testing/ws_round_trip.js +19 -11
  263. package/dist/ui/AdminAccounts.svelte +23 -20
  264. package/dist/ui/AdminOverview.svelte +15 -13
  265. package/dist/ui/AdminOverview.svelte.d.ts.map +1 -1
  266. package/dist/ui/{AdminPermitHistory.svelte → AdminRoleGrantHistory.svelte} +12 -12
  267. package/dist/ui/AdminRoleGrantHistory.svelte.d.ts +4 -0
  268. package/dist/ui/AdminRoleGrantHistory.svelte.d.ts.map +1 -0
  269. package/dist/ui/BootstrapForm.svelte +1 -1
  270. package/dist/ui/CLAUDE.md +60 -60
  271. package/dist/ui/{PermitOfferForm.svelte → RoleGrantOfferForm.svelte} +27 -26
  272. package/dist/ui/{PermitOfferForm.svelte.d.ts → RoleGrantOfferForm.svelte.d.ts} +7 -7
  273. package/dist/ui/RoleGrantOfferForm.svelte.d.ts.map +1 -0
  274. package/dist/ui/{PermitOfferHistory.svelte → RoleGrantOfferHistory.svelte} +12 -12
  275. package/dist/ui/{PermitOfferHistory.svelte.d.ts → RoleGrantOfferHistory.svelte.d.ts} +4 -4
  276. package/dist/ui/RoleGrantOfferHistory.svelte.d.ts.map +1 -0
  277. package/dist/ui/{PermitOfferInbox.svelte → RoleGrantOfferInbox.svelte} +14 -14
  278. package/dist/ui/{PermitOfferInbox.svelte.d.ts → RoleGrantOfferInbox.svelte.d.ts} +4 -4
  279. package/dist/ui/RoleGrantOfferInbox.svelte.d.ts.map +1 -0
  280. package/dist/ui/SignupForm.svelte +1 -1
  281. package/dist/ui/SurfaceExplorer.svelte +35 -15
  282. package/dist/ui/SurfaceExplorer.svelte.d.ts.map +1 -1
  283. package/dist/ui/account_sessions_state.svelte.d.ts +2 -3
  284. package/dist/ui/account_sessions_state.svelte.d.ts.map +1 -1
  285. package/dist/ui/account_sessions_state.svelte.js +2 -3
  286. package/dist/ui/admin_accounts_state.svelte.d.ts +18 -18
  287. package/dist/ui/admin_accounts_state.svelte.d.ts.map +1 -1
  288. package/dist/ui/admin_accounts_state.svelte.js +16 -16
  289. package/dist/ui/admin_rpc_adapters.d.ts +20 -20
  290. package/dist/ui/admin_rpc_adapters.d.ts.map +1 -1
  291. package/dist/ui/admin_rpc_adapters.js +17 -17
  292. package/dist/ui/admin_sessions_state.svelte.d.ts +2 -2
  293. package/dist/ui/admin_sessions_state.svelte.js +2 -2
  294. package/dist/ui/audit_log_state.svelte.d.ts +7 -7
  295. package/dist/ui/audit_log_state.svelte.d.ts.map +1 -1
  296. package/dist/ui/audit_log_state.svelte.js +6 -6
  297. package/dist/ui/auth_state.svelte.d.ts +3 -3
  298. package/dist/ui/auth_state.svelte.d.ts.map +1 -1
  299. package/dist/ui/auth_state.svelte.js +6 -6
  300. package/dist/ui/format_scope.d.ts +2 -2
  301. package/dist/ui/format_scope.js +2 -2
  302. package/dist/ui/{permit_offers_state.svelte.d.ts → role_grant_offers_state.svelte.d.ts} +30 -30
  303. package/dist/ui/role_grant_offers_state.svelte.d.ts.map +1 -0
  304. package/dist/ui/{permit_offers_state.svelte.js → role_grant_offers_state.svelte.js} +18 -18
  305. package/dist/ui/ui_format.js +2 -2
  306. package/package.json +3 -3
  307. package/dist/auth/permit_offer_action_specs.d.ts.map +0 -1
  308. package/dist/auth/permit_offer_action_specs.js +0 -258
  309. package/dist/auth/permit_offer_actions.d.ts +0 -110
  310. package/dist/auth/permit_offer_actions.d.ts.map +0 -1
  311. package/dist/auth/permit_offer_notifications.d.ts.map +0 -1
  312. package/dist/auth/permit_offer_notifications.js +0 -182
  313. package/dist/auth/permit_offer_queries.d.ts.map +0 -1
  314. package/dist/auth/permit_offer_schema.d.ts +0 -125
  315. package/dist/auth/permit_offer_schema.d.ts.map +0 -1
  316. package/dist/auth/permit_queries.d.ts +0 -222
  317. package/dist/auth/permit_queries.d.ts.map +0 -1
  318. package/dist/auth/permit_queries.js +0 -305
  319. package/dist/auth/require_keeper.d.ts +0 -20
  320. package/dist/auth/require_keeper.d.ts.map +0 -1
  321. package/dist/auth/require_keeper.js +0 -35
  322. package/dist/auth/route_guards.d.ts +0 -27
  323. package/dist/auth/route_guards.d.ts.map +0 -1
  324. package/dist/auth/route_guards.js +0 -38
  325. package/dist/auth/session_lifecycle.d.ts +0 -37
  326. package/dist/auth/session_lifecycle.d.ts.map +0 -1
  327. package/dist/auth/session_lifecycle.js +0 -29
  328. package/dist/ui/AdminPermitHistory.svelte.d.ts +0 -4
  329. package/dist/ui/AdminPermitHistory.svelte.d.ts.map +0 -1
  330. package/dist/ui/PermitOfferForm.svelte.d.ts.map +0 -1
  331. package/dist/ui/PermitOfferHistory.svelte.d.ts.map +0 -1
  332. package/dist/ui/PermitOfferInbox.svelte.d.ts.map +0 -1
  333. package/dist/ui/permit_offers_state.svelte.d.ts.map +0 -1
@@ -8,7 +8,7 @@ dispatcher, every transport adapter, the event state machine, and the
8
8
  reactive frontend client.
9
9
 
10
10
  For narrative context (consumer wiring examples, client-authoritative vs
11
- server-authoritative dispatch, permit-offer UI integration) see
11
+ server-authoritative dispatch, role-grant-offer UI integration) see
12
12
  ../../docs/usage.md §Deriving Route/Event Specs, §Single JSON-RPC 2.0 Endpoint,
13
13
  §WebSocket Endpoint. For DEV-only output validation semantics see
14
14
  ../../docs/architecture.md §DEV-only Output Validation. For the SAES
@@ -28,17 +28,17 @@ codegen helpers are post-SAES-RPC-closeout stable.
28
28
 
29
29
  Canonical source of truth. Three concrete kinds discriminate on `kind`:
30
30
 
31
- | Kind | `auth` | `side_effects` | `output` | `async` |
32
- | --------------------- | ----------------------- | -------------- | ----------- | ------- |
33
- | `request_response` | `ActionAuth` (non-null) | arbitrary | arbitrary | `true` |
34
- | `remote_notification` | `null` | `true` | `z.ZodVoid` | `true` |
35
- | `local_call` | `null` | arbitrary | arbitrary | boolean |
31
+ | Kind | `auth` | `side_effects` | `output` | `async` |
32
+ | --------------------- | ---------------------- | -------------- | ----------- | ------- |
33
+ | `request_response` | `RouteAuth` (non-null) | arbitrary | arbitrary | `true` |
34
+ | `remote_notification` | `null` | `true` | `z.ZodVoid` | `true` |
35
+ | `local_call` | `null` | arbitrary | arbitrary | boolean |
36
36
 
37
37
  Enums + unions:
38
38
 
39
39
  - `ActionKind` — `'request_response' | 'remote_notification' | 'local_call'`
40
40
  - `ActionInitiator` — `'frontend' | 'backend' | 'both'`
41
- - `ActionAuth` — `'public' | 'authenticated' | 'keeper' | {role: string}`
41
+ - `RouteAuth` — flat record `{account, actor, roles?, credential_types?}` from `http/auth_shape.ts`. Each axis (`account`, `actor`) is `'none' | 'optional' | 'required'`; `roles` and `credential_types` are optional any-of arrays. Cross-axis invariants: roles imply `actor: 'required'`; `account: 'none'` implies `actor: 'none'` (no accountless actors in v1); the unrestricted leaf (`account: 'none', actor: 'none'`) cannot declare roles or credential gates. The biconditional `actor !== 'none' ⟺ input declares acting?: ActingActor` is enforced at registration time via `assert_route_auth_acting_biconditional`.
42
42
  - `ActionSpecUnion` — discriminated union of the three variants
43
43
  - `ActionEventPhase` — `'send_request' | 'receive_request' | 'send_response' | 'receive_response' | 'send_error' | 'receive_error' | 'send' | 'receive' | 'execute'`
44
44
  - `is_action_spec(value)` — structural type guard
@@ -53,10 +53,10 @@ declarative metadata for consumers (codegen, UI form-state matching, docs)
53
53
  to read off the spec instead of scanning handler code. No runtime
54
54
  enforcement — drift between declared reasons and what handlers actually
55
55
  throw is caught per-module by source-scanning unit tests (see
56
- `../../test/auth/permit_offer_actions.error_reasons.test.ts`). Reuses
56
+ `../../test/auth/role_grant_offer_actions.error_reasons.test.ts`). Reuses
57
57
  the same `as const` string constants the handler throws (e.g.
58
- `ERROR_OFFER_*` from `../auth/permit_offer_action_specs.ts`,
59
- `ERROR_PERMIT_NOT_FOUND` from `../http/error_schemas.ts`) so call
58
+ `ERROR_ROLE_GRANT_OFFER_*` from `../auth/role_grant_offer_action_specs.ts`,
59
+ `ERROR_ROLE_GRANT_NOT_FOUND` from `../http/error_schemas.ts`) so call
60
60
  sites can import either side. Standard transport errors (validation,
61
61
  auth, rate-limit) stay implicit.
62
62
 
@@ -68,7 +68,7 @@ RPC dispatcher (`create_rpc_endpoint`) and the WebSocket dispatcher
68
68
  `request_context.account.id` (post-auth, account-grain — every
69
69
  authenticated action has an account regardless of whether an actor was
70
70
  resolved) and is rejected at registration when paired with
71
- `auth: 'public'` (no account to key on); `'both'` runs
71
+ `auth.account !== 'required'` (no account to key on); `'both'` runs
72
72
  both checks. **Throttle-requests semantics** — every invocation records,
73
73
  regardless of outcome (different from REST login's throttle-failures
74
74
  that resets on success). The motivating threat is admin mutation oracles
@@ -149,7 +149,7 @@ not the runtime):
149
149
  ### Primitives
150
150
 
151
151
  - `ImportBuilder` — tracks value / type / namespace imports; emits `import type` when every entry on a module is a type (tree-shaking). Namespace (`* as specs`) entries are emitted verbatim. Public surface: `add`, `add_type`, `add_many`, `add_types`, `build`, `preview`, `has_imports`, `import_count`, `clear`.
152
- - `get_executor_phases(spec, executor)` — phases a given executor (`'frontend' | 'backend'`) participates in for the spec. Deduplicates via `Set` (handles `initiator: 'both'` overlap).
152
+ - `get_executor_phases(spec, executor)` — phases a given executor (`'frontend' | 'backend'`) participates in for the spec. Branch-aware: the backend `can_receive` branch only pushes `send_error` when `!can_send`, so `initiator: 'both'` doesn't double-count and no `Set` dedup is needed.
153
153
  - `get_handler_return_type(spec, phase, imports, collections_path?)` — the TS type a phase handler must return; triggers the `ActionOutputs` import (sourced from `collections_path`, default `'./action_collections.js'`) as a side effect.
154
154
  - `generate_phase_handlers(spec, executor, imports, {action_event_type?, collections_path?})` — emits the typed handler-map fragment for one action; consumers compose these into `ActionHandlers` types. Returns `''` when the spec contributes no phases on the given executor (e.g. a backend-only `local_call` asked for `'frontend'`) so wrappers' `.filter(Boolean)` drops the row entirely instead of emitting a useless `${method}?: never` for a method that doesn't belong on this side.
155
155
  - `generate_actions_api_method_signature(spec, imports, {sync_returns_value?, collections_path?})` — single source of truth for the typed `FrontendActionsApi` method shape. Threads `options?: RpcClientCallOptions` (`{signal?, transport_name?, queue?}`) onto every async method — `request_response`, `remote_notification`, and async `local_call` — and wraps the return in `Promise<Result<...>>`. Registers exactly the imports the emitted line references on `imports` — `ActionInputs` only when the spec has input, `RpcClientCallOptions` only when async, `Result` / `JsonrpcErrorObject` only when the return wraps in `Result`. Mirrors the leaf-level pattern `get_handler_return_type` already follows so wrappers no longer pre-register imports a per-spec emit might not actually use.
@@ -160,6 +160,7 @@ not the runtime):
160
160
  - `DEFAULT_COLLECTIONS_PATH = './action_collections.js'` — shared default for every helper that takes a `collections_path?`.
161
161
  - `DEFAULT_SPECS_MODULE = './action_specs.js'` — shared default for helpers that emit `specs.{method}_action_spec` and need a `* as specs` namespace import.
162
162
  - `DEFAULT_METATYPES_PATH = './action_metatypes.js'` — shared default for the sibling module carrying the generated `ActionMethod` enum.
163
+ - `resolve_spec_qualifier(imports, {specs_module?, qualify_spec?})` — the standard default-vs-callback resolver every multi-source-aware helper in this module uses. With `qualify_spec` set, returns the callback verbatim (consumer owns its namespace setup); otherwise registers `* as specs from specs_module` (default `DEFAULT_SPECS_MODULE`) on `imports` and returns `(s) => 'specs.' + to_action_spec_identifier(s.method)`. Reuse from custom codegen helpers instead of reimplementing the defaulting + import-registration dance.
163
164
 
164
165
  ### High-level helpers
165
166
 
@@ -181,9 +182,9 @@ protocol actions in their typed API.
181
182
  **Consumer tiers and namespace handling.** Single-source consumers (zzz,
182
183
  undying — every spec lives in one local `action_specs.ts`) drop straight
183
184
  into the helpers and accept the default `* as specs from specs_module`
184
- namespace import. Multi-source consumers (tx, visiones — which stitch
185
+ namespace import. Multi-source consumers (zap, visiones — which stitch
185
186
  local specs together with `all_admin_action_specs` /
186
- `all_permit_offer_action_specs` / `all_account_action_specs` /
187
+ `all_role_grant_offer_action_specs` / `all_account_action_specs` /
187
188
  `all_self_service_role_action_specs` from fuz_app) call
188
189
  `create_namespace_qualifier(sources, imports)` once, then pass the
189
190
  returned `qualify_spec` callback to the multi-source helpers
@@ -196,7 +197,7 @@ multi-namespace imports. The helper appends `.input` / `.output` to the
196
197
  qualified identifier in `generate_action_inputs_outputs` automatically;
197
198
  the callback returns the bare spec identifier.
198
199
 
199
- Tier 1 (HTTP-only, e.g. tx/visiones) emits a smaller surface — typically just
200
+ Tier 1 (HTTP-only, e.g. zap/visiones) emits a smaller surface — typically just
200
201
  `ActionMethod` + `FrontendActionsApi` + `ActionInputs` / `ActionOutputs`
201
202
  interfaces — and never calls `generate_typed_action_event_alias` or
202
203
  `generate_frontend_action_handlers`. Tier 2 (`TypedActionEvent`-aware, e.g.
@@ -217,47 +218,69 @@ and `FrontendActionHandlers`.
217
218
  ### Wrapper + multi-source helper
218
219
 
219
220
  - `compose_gen_file({origin_path, imports, blocks})` — encapsulates the per-`*.gen.ts` boilerplate (banner + `imports.build()` + blocks join + template literal). Returns the full file body. Each consumer producer collapses to one `compose_gen_file` call wrapping the helper invocations.
220
- - `create_namespace_qualifier(sources, imports)` — multi-source consumer helper. Takes `ReadonlyArray<{ns, module, specs}>`, registers `import * as ns from module` for each on `imports`, builds the `method_to_ns` lookup with duplicate-method detection, returns `{qualify_spec, all_specs}` ready to thread through the high-level helpers. Closes the per-file boilerplate gap that kept tx + visiones on hand-rolled template strings even after the `qualify_spec?` callback landed (the per-call callback wasn't enough — the import dance + dup-check was the real boilerplate).
221
+ - `create_namespace_qualifier(sources, imports)` — multi-source consumer helper. Takes `ReadonlyArray<{ns, module, specs}>`, registers `import * as ns from module` for each on `imports`, builds the `method_to_ns` lookup with duplicate-method detection, returns `{qualify_spec, all_specs}` ready to thread through the high-level helpers. Closes the per-file boilerplate gap that kept zap + visiones on hand-rolled template strings even after the `qualify_spec?` callback landed (the per-call callback wasn't enough — the import dance + dup-check was the real boilerplate).
221
222
 
222
223
  ## HTTP bridge (`action_bridge.ts`)
223
224
 
224
225
  Derives transport-specific specs from action specs. HTTP-specific concerns
225
226
  (path, handler, errors) come from options, not the action spec.
226
227
 
227
- - `create_action_route_spec(spec, options)` — one action → one `RouteSpec`. HTTP method defaults by `side_effects` (`true` → POST, `false` → GET; override via `options.http_method`). Auth maps via `map_action_auth` (`'public'` `{type: 'none'}`, `'authenticated'` `{type: 'authenticated'}`, `'keeper'` `{type: 'keeper'}`, `{role}` → `{type: 'role', role}`). `options.errors: RouteErrorSchemas` attaches transport-specific (HTTP status–keyed) error shapes. `transaction: spec.side_effects`. Throws if `spec.auth` is null.
228
+ - `create_action_route_spec(spec, options)` — one action → one `RouteSpec`. HTTP method defaults by `side_effects` (`true` → POST, `false` → GET; override via `options.http_method`). `route.auth` is `spec.auth` verbatim (the same `RouteAuth` shape governs both surfaces). `options.errors: RouteErrorSchemas` attaches transport-specific (HTTP status–keyed) error shapes. `transaction: spec.side_effects`. Throws if `spec.auth` is null.
228
229
  - `create_action_event_spec(spec, {channel?})` — one notification action → one `EventSpec` for SSE surface + `create_validated_broadcaster`. Throws on non-`remote_notification` kind.
229
- - `map_action_auth(auth)` / `derive_http_method(side_effects)` — exported for consumers that build custom bridges.
230
+ - `derive_http_method(side_effects)` — exported for consumers that build custom bridges.
230
231
 
231
232
  ## Single JSON-RPC 2.0 endpoint (`action_rpc.ts`)
232
233
 
233
234
  `create_rpc_endpoint({path, actions, log}): RouteSpec[]` produces **two**
234
235
  route specs on the same path (GET + POST) that share one internal
235
236
  dispatcher. Per-action auth lives inside the dispatcher; the outer routes
236
- use `auth: {type: 'none'}` and `transaction: false`.
237
+ use `auth: {account: 'none', actor: 'none'}` and `transaction: false`.
237
238
 
238
- Dispatcher phase order (POST; GET differs only at step 1). Mirrors the
239
- REST authorization order in `http/route_spec.ts` so HTTP RPC and REST
240
- fail with the same priority (401 403 → 400 → handler):
239
+ The HTTP RPC dispatcher is a thin shim around `perform_action`
240
+ (`actions/perform_action.ts`). The shim owns the wire-shape concerns
241
+ (envelope parsing, GET vs POST split, `c.json` binding); the
242
+ auth/validation/dispatch pipeline is shared with the WebSocket
243
+ dispatcher.
244
+
245
+ Phase order: **401 → 400 → 403 → handler** — validate first, authorize
246
+ after. The trade-off is that an unauthorized caller sees the validation
247
+ step; the alternative ordering (403-before-400) was rejected because
248
+ defense-in-depth via attack-surface obscurity is illusory when the
249
+ surface is published in `library.json` codegen anyway.
250
+
251
+ Shim responsibilities:
241
252
 
242
253
  1. **Parse envelope** — POST body as `JsonrpcRequest` (parse errors → JSON-RPC `parse_error` 400). GET reads `method`, `id`, `params` from query string; missing `method`/`id` → 400 `invalid_request`. Integer `id` normalization: `?id=42` matches `{id: 42}`.
243
- 2. **Lookup method** — `Map<method, RpcAction>`. Unknown method → `method_not_found`. Duplicate methods throw at construction.
244
- 3. **GET read restriction** — GET is rejected for `side_effects: true` actions (`invalid_request` with "must use POST").
245
- 4. **Pre-validation auth** — `check_action_auth_pre_validation(spec.auth, account_id)`. Short-circuits with `unauthenticated` (-32001 / 401) when `auth !== 'public'` and no `ACCOUNT_ID_KEY` is on the request. Fires before input validation so unauthenticated callers don't leak `invalid_params` for methods with required input. Public actions skip the rest of the auth path.
246
- 5. **Authorization phase** — for non-public actions, when `is_actor_implying_auth(spec.auth)` (`'keeper'` or `{role}`) or `input_schema_declares_acting(spec.input)` (the input has the canonical `acting?: ActingActor` field), `apply_authorization_phase` resolves the actor against `c.var.account_id` plus the raw `acting` string read off `params` (no schema validation yet), builds the `{account, actor, permits}` `RequestContext`, and sets `REQUEST_CONTEXT_KEY`. Authenticated-but-actor-less routes still build an account-only context via `build_account_context`. Resolution failures come back as `AuthorizationFailure` (`{status, body}`) the auth domain stops short of producing a `Response` so each transport binds it. The RPC dispatcher folds the failure into a JSON-RPC envelope: `error.code` from `http_status_to_jsonrpc_error_code(failure.status)` (400 `invalid_params` for `actor_required` / `actor_not_on_account`, 500 → `internal_error` for `no_actors_on_account` and `account_vanished`), `error.message` from the reason string, and `error.data: {reason, ...rest}` flattens any diagnostic fields (e.g. `available[]` for `actor_required`). The two 500 reasons are kept distinct: `no_actors_on_account` names a signup invariant violation (the actor enumeration succeeded and came back empty); `account_vanished` names a torn-read race (the account or actor row was deleted between credential validation and the dispatcher's follow-up `build_request_context` / `build_account_context` step). REST emits the same `body` directly via `c.json(body, status)` so its surface stays consistent with other middleware-emitted plain bodies. See `../auth/CLAUDE.md` § Middleware and the root `../../../CLAUDE.md` § Cleanest architecture takes priority for the rationale.
247
- 6. **Post-authorization auth** — `check_action_auth_post_authorization(spec.auth, request_context, credential_type)`. `keeper` requires `credential_type === 'daemon_token'` AND `has_role(request_context, 'keeper')` — the `has_role` alone is insufficient, session/bearer cannot elevate; failure attaches `{reason: ERROR_KEEPER_REQUIRES_DAEMON_TOKEN, credential_type}` under `error.data`. `{role}` uses `has_role`; failure attaches `{reason: ERROR_INSUFFICIENT_PERMISSIONS, required_role}`. Both surface as `forbidden` (-32002 / 403). `'authenticated'` already cleared step 4.
248
- 7. **Validate params** — `spec.input.safeParse(params)` where `params` is `raw_params` for `z.void()` schemas, otherwise `raw_params ?? {}` (HTTP convention: empty body = empty object). Registration rejects `z.null()` inputs because JSON-RPC 2.0 §4.2 forbids `params: null`. Failure → `invalid_params` with `{issues}`.
249
- 8. **Rate limit** — `spec.rate_limit` (`'ip' | 'account' | 'both'`); shared limiter pair with the WS dispatcher. Throttle-requests semantics — every invocation records, regardless of outcome. Account-keyed limiting bills `request_context.account.id` (every authenticated action has one). Failure → `rate_limited` (-32006 / 429) with `{retry_after}`.
250
- 9. **Dispatch** — `spec.side_effects` picks transaction (`route.db.transaction(tx => execute(tx))`) vs pool (`route.db`). Handler throws roll back the transaction — the catch sits outside the transaction boundary.
251
- 10. **DEV-only output validation** — `spec.output.safeParse(output)` runs only under `DEV` (from `esm-env`). On mismatch: `log.error(...)`, return response unchanged; never throws, never mutates status.
252
-
253
- Error paths: `ThrownJsonrpcError` (duck-typed via `err instanceof Error &&
254
- typeof err.code === 'number'`) preserves code + data verbatim, status via
255
- `jsonrpc_error_code_to_http_status`. Duck-typing avoids cross-copy
256
- `instanceof` misses when consumers throw their own `ThrownJsonrpcError`
257
- (e.g. zzz). Generic thrown errors become `internal_error` 500; message is
258
- the raw error under `DEV`, "internal server error" otherwise.
259
-
260
- Per-request handler shape:
254
+ 2. **Lookup method** — `Map<method, RpcAction>`. Unknown method → `method_not_found`. Duplicate methods throw at construction. Registration also runs `assert_route_auth_acting_biconditional(spec.auth, {input: spec.input}, ...)` to enforce invariant 2 — the helper takes a `{input, query?}` slot set so REST (input + query bi-located) and actions (input-only) share one entry point with surface-appropriate error messages.
255
+ 3. **GET read restriction** — GET is rejected for `side_effects: true` actions (`invalid_request` with "must use POST"). HTTP-only.
256
+ 4. **Build PerformActionInput** — read `account_id` / `credential_type` from `c.var`, resolve `client_ip` via `get_client_ip`, pass `c.req.raw.signal` as `signal`, build a DEV-warn-and-drop `notify`. Test-preset escape hatch reads `TEST_CONTEXT_PRESET_KEY` + `REQUEST_CONTEXT_KEY` and forwards as `preset.request_context`.
257
+ 5. **Call `perform_action`**runs steps 1–6 of the shared pipeline (see §Shared dispatch core below).
258
+ 6. **Bind result** — `perform_action_result_to_envelope(id, result)` builds the JSON-RPC wire envelope; `c.json(envelope, result.status)` returns it.
259
+
260
+ The shared core inside `perform_action` runs:
261
+
262
+ - Pre-validation auth (401), input validation (400), authorization phase (with `apply_authorization_phase` resolving the actor from `validated_input.acting`), post-authorization auth (403 — credential gate first, role gate second), rate limit (429), transactional dispatch + DEV output validation, error normalization.
263
+
264
+ Resolution failures from the authorization phase come back as
265
+ `AuthorizationResult.ok === false` carrying `{status, body}`
266
+ `perform_action` folds this into a JSON-RPC envelope where `error.code`
267
+ maps from `http_status_to_jsonrpc_error_code(result.status)`,
268
+ `error.message` is the reason string, and `error.data: {reason, ...rest}`
269
+ flattens any diagnostic fields (e.g. `available[]` for `actor_required`).
270
+ The two 500 reasons stay distinct: `no_actors_on_account` (signup
271
+ invariant violation — the actor enumeration came back empty);
272
+ `account_vanished` (torn read after resolve). REST emits the same `body`
273
+ directly via `c.json(body, status)` for surface consistency.
274
+
275
+ Error paths: `ThrownJsonrpcError` (duck-typed via `err instanceof Error
276
+ && typeof err.code === 'number'`) preserves code + data verbatim. Duck-
277
+ typing avoids cross-copy `instanceof` misses when consumers throw their
278
+ own `ThrownJsonrpcError` (e.g. zzz). Generic thrown errors become
279
+ `internal_error` 500; message is the raw error under `DEV`, "internal
280
+ server error" otherwise. The HTTP shim's outer `c.json` then binds the
281
+ status.
282
+
283
+ Per-request handler shape (uniform across HTTP RPC + WS):
261
284
 
262
285
  ```ts
263
286
  type ActionHandler<TInput, TOutput> = (
@@ -268,12 +291,14 @@ type ActionHandler<TInput, TOutput> = (
268
291
  interface ActionContext {
269
292
  auth: RequestContext | null; // null for public actions
270
293
  request_id: JsonrpcRequestId;
294
+ connection_id?: Uuid; // populated on WS, undefined on HTTP
271
295
  db: Db; // transaction for mutations, pool for reads
272
- background_db: Db; // always pool — for fire-and-forget outlive
273
- pending_effects: Array<Promise<void>>;
296
+ pending_effects: Array<Promise<void>>; // eager pool writes already in flight see http/CLAUDE.md §Pending Effects
297
+ post_commit_effects: Array<() => void | Promise<void>>; // deferred — push via `emit_after_commit`
298
+ client_ip: string;
274
299
  log: Logger;
275
- notify: (method, params) => void; // HTTP: DEV-mode warn + drop (no streaming channel)
276
- signal: AbortSignal; // c.req.raw.signal fires on client disconnect
300
+ notify: (method, params) => void; // HTTP: DEV-mode warn + drop (no streaming channel); WS: socket-scoped
301
+ signal: AbortSignal; // HTTP: client-disconnect; WS: AbortSignal.any([socket_close, request_cancel])
277
302
  }
278
303
 
279
304
  interface RpcAction {
@@ -282,79 +307,65 @@ interface RpcAction {
282
307
  }
283
308
  ```
284
309
 
285
- ### `rpc_action(spec, handler)` — typed binder
310
+ ### `rpc_action(spec, handler)` — typed binder with conditional `ctx.auth` narrowing
286
311
 
287
312
  `rpc_action<TSpec extends RequestResponseActionSpec>(spec, handler)`
288
- returns a `RpcAction` with the handler's input / output types pinned to
289
- `z.infer<TSpec['input']>` and `z.infer<TSpec['output']>` via the generic.
313
+ returns a `RpcAction` with the handler's input / output types pinned
314
+ to `z.infer<TSpec['input']>` / `z.infer<TSpec['output']>` and the
315
+ handler's `ctx.auth` slot tightened to the narrowest shape the
316
+ dispatcher's runtime guarantee allows. The conditional `HandlerForSpec<TSpec>`
317
+ discriminates on the spec literal:
318
+
319
+ | Spec auth axes | Selected handler type | `ctx.auth` |
320
+ | ------------------------------------------------------ | --------------------- | ------------------------ |
321
+ | `auth.actor === 'required'` | `ActorActionHandler` | `RequestActorContext` |
322
+ | `auth.account === 'required' && auth.actor === 'none'` | `AuthActionHandler` | `RequestContext` |
323
+ | else (public, optional axes) | `ActionHandler` | `RequestContext \| null` |
324
+
290
325
  Use this at every spec → handler binding site so handler-type errors
291
326
  surface at the factory call instead of at runtime:
292
327
 
293
328
  ```ts
294
- export const create_account_actions = (deps, options) => [
295
- rpc_action(account_verify_action_spec, verify_handler),
296
- rpc_action(account_session_list_action_spec, session_list_handler),
329
+ // actor-implying spec ctx.auth: RequestActorContext (actor non-null)
330
+ rpc_action(role_grant_revoke_action_spec, async (input, ctx) => {
331
+ const revoker_id = ctx.auth.actor.id;
297
332
  // …
298
- ];
333
+ });
334
+
335
+ // account-grain spec → ctx.auth: RequestContext (actor: null)
336
+ rpc_action(account_verify_action_spec, (_input, ctx) => {
337
+ return to_session_account(ctx.auth.account);
338
+ });
299
339
  ```
300
340
 
341
+ The bracketed form `[T] extends ['required']` defeats distributive
342
+ conditionals so a degraded `AuthAxisState` union (when the spec was
343
+ typed without preserving its literal) falls through to the loosest
344
+ tier instead of collapsing to the narrowest. Specs declared with
345
+ `satisfies RequestResponseActionSpec` (canonical) preserve the
346
+ literals — typing a spec directly as `RequestResponseActionSpec`
347
+ widens the axes and silently drops the ergonomic narrowing (the
348
+ binder still compiles; consumers just lose the auto-narrow on
349
+ `ctx.auth`).
350
+
301
351
  zzz uses a codegen-driven `Record<Method, Handler>` map for the same
302
352
  narrowing — ideal when handlers are stateless free functions. fuz_app's
303
- handlers close over factory-captured deps (`log`, `on_audit_event`,
353
+ handlers close over factory-captured deps (`log`, `audit`,
304
354
  `options.app_settings`, `options.max_tokens`), so per-pair typing via
305
355
  `rpc_action()` is the right shape here: the binding happens at
306
356
  construction time and the handler keeps its closure. Applied across
307
- `account_actions.ts` for the account-grain self-service surface (auth:
308
- `'authenticated'`, no `acting` in input — the dispatcher does not
309
- resolve an actor); the actor-implying registries (`admin_actions.ts`,
310
- `permit_offer_actions.ts`, `self_service_role_actions.ts`) use the
311
- `rpc_actor_action` variant below.
312
-
313
- ### `rpc_actor_action(spec, handler)` actor-narrowed variant
314
-
315
- Sibling factory for handlers whose dispatcher always resolves an acting
316
- actor actions with `auth: 'keeper' | {role}` or input that declares
317
- `acting?: ActingActor`. The dispatcher's authorization phase populates
318
- `ctx.auth` with a non-null `RequestActorContext` before any of these
319
- handlers runs, so `rpc_actor_action`'s handler signature types
320
- `ctx: ActionActorContext` (with `auth: RequestActorContext`) and the
321
- handler body skips the `require_request_actor(ctx.auth)` narrowing
322
- call:
323
-
324
- ```ts
325
- rpc_actor_action(permit_revoke_action_spec, async (input, ctx) => {
326
- // ctx.auth is RequestActorContext — no narrowing needed.
327
- const revoker_id = ctx.auth.actor.id;
328
- // …
329
- });
330
- ```
331
-
332
- The runtime binding is identical to `rpc_action` — both register the
333
- same `RpcAction` shape on the action map. The change is compile-time
334
- only: forgetting the actor narrowing on an actor-implying action used
335
- to require either an `auth.actor!` non-null assertion or a
336
- `require_request_actor` call; `rpc_actor_action` lets the type
337
- reflect what the dispatcher already guarantees, which closes the bug
338
- class where the narrowing call is missed and the handler is left
339
- operating against a possibly-null actor.
340
-
341
- Applied uniformly across the actor-implying registries: every handler
342
- in `admin_actions.ts` (all eleven specs declare `auth: {role: 'admin'}`
343
-
344
- - `acting: ActingActor` on input, so the dispatcher always resolves an
345
- actor — list-style handlers that don't read `ctx.auth.actor` still bind
346
- through `rpc_actor_action` for type-uniformity), every handler in
347
- `permit_offer_actions.ts` (every spec there declares
348
- `acting: ActingActor`), and the single `self_service_role_set` handler
349
- in `self_service_role_actions.ts`. The rule is "actor-implying spec →
350
- `rpc_actor_action`" regardless of whether the handler body reads
351
- `ctx.auth.actor` — the dispatcher's runtime guarantee is what the type
352
- should reflect, and uniform binding keeps a future handler that does
353
- need the actor from accidentally landing on the looser binder.
354
- Account-grain handlers in `account_actions.ts` keep `rpc_action`:
355
- their auth is `'authenticated'`, their inputs don't declare `acting`,
356
- so the dispatcher genuinely runs in `needs_actor: false` mode and
357
- `ctx.auth.actor` is null.
357
+ all four registries `admin_actions.ts`,
358
+ `role_grant_offer_actions.ts`, `self_service_role_actions.ts` (every
359
+ spec there is actor-implying), and `account_actions.ts` (account-grain).
360
+ The conditional auto-selects the right tier per spec; consumers don't
361
+ pick a binder.
362
+
363
+ The earlier two-binder split (`rpc_action` + `rpc_actor_action`) was
364
+ collapsed once the symmetric account-grain narrowing landed. Same
365
+ runtime; the second symbol no longer added information the spec
366
+ literal didn't already carry. Uniform binding keeps a future handler
367
+ that gains `ctx.auth.actor` reads from accidentally landing on a
368
+ looser narrow the spec literal drives the type either way.
358
369
 
359
370
  ## Transports (`transports.ts`, `transports_http.ts`, `transports_ws.ts`, `transports_ws_backend.ts`)
360
371
 
@@ -435,7 +446,7 @@ Fan-out:
435
446
 
436
447
  - `send(notification)` — broadcasts to every connection (current `send(request)` returns an internal_error "not yet implemented" — backend cannot initiate request-response).
437
448
  - `broadcast_filtered(message, predicate)` — per-connection predicate over `ConnectionIdentity`; skips non-matching. Returns count.
438
- - `send_to_account(account_id, message)` — targeted wrapper over `broadcast_filtered`. Mirrors `close_sockets_for_account` on the send side (every connection for the account). Structurally satisfies the `NotificationSender` interface from `auth/permit_offer_notifications.ts` (see `../auth/CLAUDE.md` §WS notifications).
449
+ - `send_to_account(account_id, message)` — targeted wrapper over `broadcast_filtered`. Mirrors `close_sockets_for_account` on the send side (every connection for the account). Structurally satisfies the `NotificationSender` interface from `auth/role_grant_offer_notifications.ts` (see `../auth/CLAUDE.md` §WS notifications).
439
450
  - `get_connection_count()` — telemetry counter over the connection map.
440
451
 
441
452
  Return values are bookkeeping, not delivery receipts — `0` means no live
@@ -450,7 +461,7 @@ guard in `realtime/sse_auth_guard.ts` but targets the WS transport.
450
461
 
451
462
  `WS_DISCONNECT_EVENT_TYPES` (ReadonlySet): `session_revoke`,
452
463
  `token_revoke`, `session_revoke_all`, `token_revoke_all`, `password_change`.
453
- `permit_revoke` is intentionally **omitted** — the WS transport does not
464
+ `role_grant_revoke` is intentionally **omitted** — the WS transport does not
454
465
  track per-connection role requirements, so role-scoped disconnection would
455
466
  require either closing all sockets (too aggressive) or new per-connection
456
467
  role tracking (out of scope). Consumers that need it compose their own
@@ -495,57 +506,74 @@ Composes the standard upgrade stack:
495
506
 
496
507
  1. `verify_request_source(allowed_origins)`
497
508
  2. `require_auth`
498
- 3. optional `require_role(required_role)`
499
- 4. delegates to `register_action_ws`
509
+ 3. upgrade-time authorization phase — resolves the acting actor and seeds `REQUEST_CONTEXT_KEY` for the inner `register_action_ws`'s upgrade-time identity capture
510
+ 4. optional `require_role([required_role])` (single-element array form)
511
+ 5. delegates to `register_action_ws`
500
512
 
501
- Extends `RegisterActionWsOptions<TCtx>` with `allowed_origins: Array<RegExp>`
513
+ Extends `RegisterActionWsOptions` with `allowed_origins: Array<RegExp>`
502
514
  and optional `required_role: RoleName`. Returns `{transport}`. Note:
503
515
  `required_role` is a **coarse upgrade-time gate** — per-action `auth` in
504
- each spec still applies at dispatch time. (`verify_request_source` and
505
- `require_auth` / `require_role` are from `../auth/`; see
506
- `../auth/CLAUDE.md` §Middleware for their semantics.)
516
+ each spec still applies at dispatch time via `perform_action`.
517
+ (`verify_request_source` and `require_auth` / `require_role` are from
518
+ `../auth/`; see `../auth/CLAUDE.md` §Middleware for their semantics.)
507
519
 
508
520
  ### `register_action_ws` (`register_action_ws.ts`) — lower-level
509
521
 
510
522
  Exposed for tests (`create_ws_test_harness`) that need to drive the
511
523
  dispatcher without the origin/auth front-stack.
512
524
 
513
- Actions are passed as `ReadonlyArray<Action<TCtx>>` — the composable
525
+ Actions are passed as `ReadonlyArray<Action>` — the composable
514
526
  `{spec, handler?}` tuple shared with `create_rpc_client`. The dispatcher
515
- fans the array into a `spec_by_method` map (drives auth + validation) and
516
- a `handlers` record (drives invocation). Spec without handler is fine for
517
- client-only specs (incoming notification specs); spec without handler that
518
- the dispatcher is asked to invoke returns `method_not_found`.
519
-
520
- `extend_context(base, c)` builds the per-request context on every message.
521
- `BaseHandlerContext` (the non-extended minimum, exported from `action_types.ts`):
522
-
523
- ```ts
524
- interface BaseHandlerContext {
525
- request_id: JsonrpcRequestId;
526
- connection_id: Uuid; // stable across messages on this socket
527
- notify: (method, params) => void; // socket-scoped, not broadcast
528
- signal: AbortSignal; // AbortSignal.any([socket_close, per_request_cancel])
529
- }
530
- ```
531
-
532
- `WsActionHandler<TCtx>` is the WS-side handler type (single-context-slot,
533
- returns `unknown`disambiguated from `action_rpc.ts`'s `ActionHandler`).
534
-
535
- Per-message wire behavior:
527
+ fans the array into a `spec_by_method` map (drives envelope-shape
528
+ validation) and an `action_map: Map<string, RpcAction>` (drives
529
+ invocation, only request_response specs with a handler). Specs without
530
+ a handler (client-only / dispatcher-handled like `cancel`) miss
531
+ `action_map` and surface as `method_not_found` if the wire targets them.
532
+
533
+ Required deps: `db: Db` (pool-level, used by `perform_action` for both the
534
+ per-message authorization phase and the transactional dispatch wrap when
535
+ `spec.side_effects: true`). Audit fan-out and other rollback-resilient
536
+ fire-and-forget writes run through `AppDeps.audit` from each action
537
+ factory's closure — the dispatcher never holds a separate pool reference.
538
+
539
+ Per-message dispatch delegates to `perform_action` (`actions/perform_action.ts`)
540
+ the shared core that HTTP RPC also calls. `register_action_ws` only owns
541
+ WS-specific concerns:
542
+
543
+ - **Wire envelope parsing** — JSON.parse → batch rejection → notification interception (cancel, silent drop) → per-message dispatch.
544
+ - **Cancel-notification interception** — `{request_id AbortController}` map; aborts the matching pending controller before the cancel bubbles past the dispatcher.
545
+ - **Socket-scoped notify** `(method, params) => ws.send(notification)`, threaded into `perform_action` as `notify`.
546
+ - **Composed abort signal** — `AbortSignal.any([socket_close, per_request_cancel])`, threaded into `perform_action` as `signal`.
547
+ - **Connection lifecycle** — `transport.add_connection` / `remove_connection`, `on_socket_open` / `_close` hooks, server heartbeat.
548
+
549
+ Per-message authorization phase: `perform_action` calls
550
+ `apply_authorization_phase` per-message (HTTP and WS uniformly). Role grant
551
+ changes during a connection lifetime are picked up on the next message —
552
+ no in-place refresh, no socket-close on `role_grant_revoke`. Authentication
553
+ invalidation (`session_revoke`, `password_change`, `token_revoke_all`)
554
+ still closes the socket via `create_ws_auth_guard`.
555
+
556
+ Per-message wire behavior (every step delegated to `perform_action`
557
+ except the WS-specific framing):
536
558
 
537
559
  - **Batch JSON-RPC rejected** — arrays get `invalid_request`.
538
560
  - **Notifications** — method + no id. Intercepted: `cancel` aborts the matching per-request controller; other notifications are silenced per JSON-RPC spec (no consumer notification handlers yet).
539
- - **Per-action auth** — `public` / `authenticated` pass through (upgrade already verified); `keeper` requires `credential_type === 'daemon_token'` AND `has_role(ROLE_KEEPER)`; `{role}` requires `has_role(role)`. Same shape as `action_rpc.ts`.
540
- - **Input validation** — `spec.input.safeParse(params)`; failure `invalid_params` with `{issues}`.
541
- - **DEV-only output validation** — `spec.output.safeParse(output)` under `DEV`; logs error on mismatch, never throws, sends result unchanged. Uniform with RPC + REST surfaces.
542
- - **Error handling** — `ThrownJsonrpcError` preserves code + data; generic throws are wrapped via `create_jsonrpc_error_response_from_thrown`. `ThrownJsonrpcError` is logged at `debug` (expected protocol outcome); generic errors at `error`.
561
+ - **Per-action auth + validation + dispatch** — uniform with HTTP RPC via `perform_action`: pre-validation auth (401) input validation (400) authorization phase post-authorization auth (403) rate limit (429) handler under transaction (when `side_effects: true`) → DEV output validation.
562
+ - **Error handling** — handler throws normalize via `perform_action`'s thrown-error path. `ThrownJsonrpcError` preserves code + data; generic throws become `internal_error`. The WS shim sends the resulting envelope over the socket.
543
563
 
544
564
  Two abort signals, composed via `AbortSignal.any`:
545
565
 
546
566
  - `socket_abort_controller` — per-socket, fires on close. Drives every handler's `ctx.signal` on that socket.
547
567
  - `pending_controllers: Map<JsonrpcRequestId, AbortController>` — per-request. Registered before dispatch, cleared in `finally` so late cancels for a completed id (or a reused id) can't null-abort the wrong handler. Unknown cancels no-op.
548
568
 
569
+ Per-message side-effect queues: `pending_effects: Array<Promise<void>>`
570
+ (eager) drains via `flush_pending_effects`; `post_commit_effects: Array<() => void | Promise<void>>`
571
+ (deferred — pushed by handlers via `emit_after_commit`) drains via
572
+ `flush_post_commit_effects`. Both flush in the same `try/finally` that
573
+ releases the request controller, so fire-and-forget audit / notification
574
+ effects pushed by the handler complete (or reject visibly) before the
575
+ next message dispatches. See `../http/CLAUDE.md` §Pending Effects.
576
+
549
577
  Lifecycle hooks on `RegisterActionWsOptions`:
550
578
 
551
579
  - `on_socket_open({ws, connection_id, identity, notify, signal})` — fires after `transport.add_connection` but before the first message. Awaited. Throws log + close with `1011 'socket bootstrap failed'` + send an `internal_error` frame.
@@ -905,7 +933,7 @@ silently no-op because `lookup_action_handler` always returns
905
933
 
906
934
  `transport_for_method` and `on_action_event` are pure pass-throughs to
907
935
  `create_rpc_client` — exposed so consumers needing per-method routing
908
- (tx-style WS-for-actions / HTTP-for-rest split) or per-dispatch event
936
+ (zap-style WS-for-actions / HTTP-for-rest split) or per-dispatch event
909
937
  wiring (zzz-style reactive Cells observing `ActionEvent` lifecycle)
910
938
  don't have to drop down to manual `create_rpc_client` construction
911
939
  (which forfeits the bundled `api` / `api_result` pair).
@@ -943,28 +971,56 @@ natural fit when consumers already generate per-method type maps).
943
971
  ## Shared type surface (`action_types.ts`)
944
972
 
945
973
  Sits above `action_spec.ts` (pure Zod) and below the dispatchers
946
- (`register_action_ws.ts`, `action_rpc.ts`). Extracted so composable
947
- primitives (e.g. `heartbeat_action`) can name the types without pulling
948
- in server-only modules.
949
-
950
- - `BaseHandlerContext` `{request_id, connection_id, notify, signal}` (see §WebSocket dispatch for field semantics).
951
- - `WsActionHandler<TCtx>` — `(input, ctx) => unknown`. Disambiguated from HTTP's `ActionHandler`.
952
- - `Action<TCtx>` — `{spec: ActionSpecUnion, handler?: WsActionHandler<TCtx>}`. The composable unit passed to both sides' `actions` arrays. Left open for future fields (rate_limit, ACL, middleware hooks) so additions attach to the action itself instead of scattering parallel arrays.
953
-
954
- Re-exported from `register_action_ws.ts` as `Action`, `BaseHandlerContext`,
955
- `WsActionHandler` for ergonomics.
974
+ (`register_action_ws.ts`, `action_rpc.ts`, `perform_action.ts`).
975
+ Extracted so composable primitives (e.g. `heartbeat_action`) can name the
976
+ types without pulling in server-only modules.
977
+
978
+ This is the polymorphic `Action` shape only. The unified `ActionContext`
979
+ from `action_rpc.ts` is the single handler context across every
980
+ transport; `ActionHandler` is the single handler signature.
981
+
982
+ - `Action<TSpec>` `{spec: TSpec, handler?: ActionHandler}`. The composable unit passed to both sides' `actions` arrays. Polymorphic on `kind`: `request_response` specs require a handler for dispatch; `remote_notification` specs may declare a stub for symmetry but are dispatcher-handled (e.g. `cancel`); `local_call` specs never reach a network dispatcher. The WS dispatcher only invokes handlers on `request_response` actions; everything else is registry-only.
983
+
984
+ `RpcAction = Action<RequestResponseActionSpec> & {handler: ActionHandler}`
985
+ is the narrowing the HTTP RPC dispatcher accepts (`create_rpc_endpoint`)
986
+ and the `rpc_action` binder produces (the actor-axis narrowing now lives
987
+ in `HandlerForSpec<TSpec>` — there's no longer a separate
988
+ `rpc_actor_action`).
989
+
990
+ ## Shared dispatch core (`perform_action.ts`)
991
+
992
+ The transport-agnostic post-parse pipeline shared by HTTP RPC and
993
+ WebSocket. Each transport assembles a `PerformActionInput` from its wire
994
+ envelope + connection identity, calls `perform_action(input, deps)`,
995
+ and binds the discriminated `PerformActionResult` to its wire shape.
996
+
997
+ Pipeline (401 → 400 → 403 → handler):
998
+
999
+ 1. Pre-validation auth (401) — short-circuits unauthenticated callers on `'required'` axes before input validation.
1000
+ 2. Validate params (400) — `spec.input.safeParse` with `z.void()` / `?? {}` rules.
1001
+ 3. Authorization phase — `apply_authorization_phase` against `account_id` + `validated_input.acting`. Test escape hatch lives in the caller — pass `preset.request_context` to skip the live phase.
1002
+ 4. Post-authorization auth (403) — credential-type gate first, role gate second.
1003
+ 5. Rate limit (429) — per-action IP / account throttling, throttle-requests semantics (every invocation records).
1004
+ 6. Dispatch + DEV output validation + error normalization — `spec.side_effects` picks transaction (`deps.db.transaction`) vs pool. Handler throws roll back the transaction; `ThrownJsonrpcError` preserves code + data, generic throws become `internal_error`.
1005
+
1006
+ `PerformActionInput` carries `account_id`, `credential_type`, `client_ip`,
1007
+ `signal`, `notify`, optional `connection_id`, optional `preset`.
1008
+ `PerformActionDeps` carries `db` (pool-level), `pending_effects`, `log`,
1009
+ the two rate limiters. Audit writes are out-of-band: factories close over
1010
+ `AppDeps.audit` independently. `PerformActionResult` is `{kind: 'ok',
1011
+ result} | {kind: 'error', error, status}`; `perform_action_result_to_envelope(id, result)`
1012
+ builds the JSON-RPC wire shape both transports send.
956
1013
 
957
1014
  ## DEV-only output validation — uniform across surfaces
958
1015
 
959
- The critical invariant: all three action-handler surfaces apply DEV-only
960
- output validation and produce the **same failure mode** — log an error,
1016
+ The critical invariant: every action-handler surface applies DEV-only
1017
+ output validation and produces the **same failure mode** — log an error,
961
1018
  return the response unchanged, do not throw, do not mutate status.
962
1019
 
963
- | Surface | Code location | Hot path under production |
964
- | ----------------- | -------------------------------------------------------------------------------------------------------------------------- | ------------------------- |
965
- | REST bridge | `http/route_spec.ts` — `wrap_output_validation` (applied via `apply_route_specs`; inherited by `create_action_route_spec`) | short-circuit (no parse) |
966
- | JSON-RPC endpoint | `action_rpc.ts` — `if (DEV) action.spec.output.safeParse(output)` | short-circuit (no parse) |
967
- | WebSocket | `register_action_ws.ts` — `if (DEV) spec.output.safeParse(output)` | short-circuit (no parse) |
1020
+ | Surface | Code location | Hot path under production |
1021
+ | ----------------------------- | -------------------------------------------------------------------------------------------------------------------------- | ------------------------- |
1022
+ | REST bridge | `http/route_spec.ts` — `wrap_output_validation` (applied via `apply_route_specs`; inherited by `create_action_route_spec`) | short-circuit (no parse) |
1023
+ | HTTP RPC + WebSocket dispatch | `actions/perform_action.ts` — `if (DEV) spec.output.safeParse(output)` inside the shared dispatch core | short-circuit (no parse) |
968
1024
 
969
1025
  Caller-facing `input` schemas are validated **always** (DEV + production) —
970
1026
  they're the contract with external callers. Server-authored `output`
@@ -8,8 +8,9 @@
8
8
  * @module
9
9
  */
10
10
  import type { z } from 'zod';
11
- import type { ActionSpec, ActionAuth as ActionSpecAuth, ActionSideEffects } from './action_spec.js';
12
- import type { RouteSpec, RouteAuth, RouteMethod, RouteHandler } from '../http/route_spec.js';
11
+ import type { ActionSpec, ActionSideEffects } from './action_spec.js';
12
+ import type { RouteSpec, RouteMethod, RouteHandler } from '../http/route_spec.js';
13
+ import type { RouteAuth } from '../http/auth_shape.js';
13
14
  import type { EventSpec } from '../realtime/sse.js';
14
15
  import type { RouteErrorSchemas } from '../http/error_schemas.js';
15
16
  /** Options for deriving a `RouteSpec` from an `ActionSpec`. */
@@ -22,7 +23,11 @@ export interface ActionRouteOptions {
22
23
  query?: z.ZodObject;
23
24
  /** Override the default HTTP method (default: `side_effects` → POST, else GET). */
24
25
  http_method?: RouteMethod;
25
- /** Override the default auth mapping (default: `'public'` → none, `'authenticated'` → authenticated, `'keeper'` → keeper, `{role}` → role). */
26
+ /**
27
+ * Override the route's auth shape — defaults to the action spec's `auth`
28
+ * (the canonical four-axis shape from `http/auth_shape.ts` is shared
29
+ * verbatim between action specs and route specs, so no mapping is needed).
30
+ */
26
31
  auth?: RouteAuth;
27
32
  /** Handler-specific error schemas (HTTP status code → Zod schema). Transport-specific — not on ActionSpec. */
28
33
  errors?: RouteErrorSchemas;
@@ -31,8 +36,6 @@ export interface ActionRouteOptions {
31
36
  export interface ActionEventOptions {
32
37
  channel?: string;
33
38
  }
34
- /** Map an `ActionAuth` value to a `RouteAuth`. */
35
- export declare const map_action_auth: (auth: ActionSpecAuth) => RouteAuth;
36
39
  /** Derive the default HTTP method from side effects. */
37
40
  export declare const derive_http_method: (side_effects: ActionSideEffects) => RouteMethod;
38
41
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"action_bridge.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/action_bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAE3B,OAAO,KAAK,EAAC,UAAU,EAAE,UAAU,IAAI,cAAc,EAAE,iBAAiB,EAAC,MAAM,kBAAkB,CAAC;AAClG,OAAO,KAAK,EAAC,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAC,MAAM,uBAAuB,CAAC;AAC3F,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,0BAA0B,CAAC;AAEhE,+DAA+D;AAC/D,MAAM,WAAW,kBAAkB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,YAAY,CAAC;IACtB,uGAAuG;IACvG,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC;IACrB,6EAA6E;IAC7E,KAAK,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC;IACpB,mFAAmF;IACnF,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,+IAA+I;IAC/I,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,8GAA8G;IAC9G,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC3B;AAED,gEAAgE;AAChE,MAAM,WAAW,kBAAkB;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,kDAAkD;AAClD,eAAO,MAAM,eAAe,GAAI,MAAM,cAAc,KAAG,SAKtD,CAAC;AAEF,wDAAwD;AACxD,eAAO,MAAM,kBAAkB,GAAI,cAAc,iBAAiB,KAAG,WAEpE,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,wBAAwB,GACpC,MAAM,UAAU,EAChB,SAAS,kBAAkB,KACzB,SAmBF,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,wBAAwB,GACpC,MAAM,UAAU,EAChB,UAAU,kBAAkB,KAC1B,SAYF,CAAC"}
1
+ {"version":3,"file":"action_bridge.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/action_bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAE3B,OAAO,KAAK,EAAC,UAAU,EAAE,iBAAiB,EAAC,MAAM,kBAAkB,CAAC;AACpE,OAAO,KAAK,EAAC,SAAS,EAAE,WAAW,EAAE,YAAY,EAAC,MAAM,uBAAuB,CAAC;AAChF,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,0BAA0B,CAAC;AAEhE,+DAA+D;AAC/D,MAAM,WAAW,kBAAkB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,YAAY,CAAC;IACtB,uGAAuG;IACvG,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC;IACrB,6EAA6E;IAC7E,KAAK,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC;IACpB,mFAAmF;IACnF,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B;;;;OAIG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,8GAA8G;IAC9G,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC3B;AAED,gEAAgE;AAChE,MAAM,WAAW,kBAAkB;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wDAAwD;AACxD,eAAO,MAAM,kBAAkB,GAAI,cAAc,iBAAiB,KAAG,WAEpE,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,wBAAwB,GACpC,MAAM,UAAU,EAChB,SAAS,kBAAkB,KACzB,SAmBF,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,wBAAwB,GACpC,MAAM,UAAU,EAChB,UAAU,kBAAkB,KAC1B,SAYF,CAAC"}