@fuzdev/fuz_app 0.54.0 → 0.56.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 (348) hide show
  1. package/dist/actions/CLAUDE.md +214 -103
  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 +32 -0
  6. package/dist/actions/action_codegen.d.ts.map +1 -1
  7. package/dist/actions/action_codegen.js +35 -15
  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 +141 -22
  11. package/dist/actions/action_rpc.d.ts.map +1 -1
  12. package/dist/actions/action_rpc.js +106 -187
  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 +46 -40
  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 +15 -10
  34. package/dist/actions/register_ws_endpoint.d.ts.map +1 -1
  35. package/dist/actions/register_ws_endpoint.js +54 -7
  36. package/dist/actions/transports.d.ts.map +1 -1
  37. package/dist/actions/transports.js +0 -4
  38. package/dist/actions/transports_ws_auth_guard.d.ts +1 -1
  39. package/dist/actions/transports_ws_auth_guard.js +1 -1
  40. package/dist/actions/transports_ws_backend.d.ts +1 -1
  41. package/dist/actions/transports_ws_backend.js +1 -1
  42. package/dist/auth/CLAUDE.md +794 -410
  43. package/dist/auth/account_action_specs.d.ts +28 -7
  44. package/dist/auth/account_action_specs.d.ts.map +1 -1
  45. package/dist/auth/account_action_specs.js +7 -7
  46. package/dist/auth/account_actions.d.ts +7 -13
  47. package/dist/auth/account_actions.d.ts.map +1 -1
  48. package/dist/auth/account_actions.js +26 -35
  49. package/dist/auth/account_queries.d.ts +52 -16
  50. package/dist/auth/account_queries.d.ts.map +1 -1
  51. package/dist/auth/account_queries.js +87 -38
  52. package/dist/auth/account_routes.d.ts +9 -11
  53. package/dist/auth/account_routes.d.ts.map +1 -1
  54. package/dist/auth/account_routes.js +118 -46
  55. package/dist/auth/account_schema.d.ts +46 -35
  56. package/dist/auth/account_schema.d.ts.map +1 -1
  57. package/dist/auth/account_schema.js +21 -28
  58. package/dist/auth/admin_action_specs.d.ts +100 -32
  59. package/dist/auth/admin_action_specs.d.ts.map +1 -1
  60. package/dist/auth/admin_action_specs.js +64 -33
  61. package/dist/auth/admin_actions.d.ts +13 -19
  62. package/dist/auth/admin_actions.d.ts.map +1 -1
  63. package/dist/auth/admin_actions.js +37 -41
  64. package/dist/auth/audit_emitter.d.ts +160 -0
  65. package/dist/auth/audit_emitter.d.ts.map +1 -0
  66. package/dist/auth/audit_emitter.js +83 -0
  67. package/dist/auth/audit_log_queries.d.ts +17 -48
  68. package/dist/auth/audit_log_queries.d.ts.map +1 -1
  69. package/dist/auth/audit_log_queries.js +20 -56
  70. package/dist/auth/audit_log_routes.d.ts +1 -1
  71. package/dist/auth/audit_log_routes.d.ts.map +1 -1
  72. package/dist/auth/audit_log_routes.js +7 -3
  73. package/dist/auth/audit_log_schema.d.ts +92 -32
  74. package/dist/auth/audit_log_schema.d.ts.map +1 -1
  75. package/dist/auth/audit_log_schema.js +75 -46
  76. package/dist/auth/auth_guard_resolver.d.ts +44 -0
  77. package/dist/auth/auth_guard_resolver.d.ts.map +1 -0
  78. package/dist/auth/auth_guard_resolver.js +56 -0
  79. package/dist/auth/bearer_auth.d.ts +9 -7
  80. package/dist/auth/bearer_auth.d.ts.map +1 -1
  81. package/dist/auth/bearer_auth.js +13 -21
  82. package/dist/auth/bootstrap_account.d.ts +7 -7
  83. package/dist/auth/bootstrap_account.d.ts.map +1 -1
  84. package/dist/auth/bootstrap_account.js +7 -7
  85. package/dist/auth/bootstrap_routes.d.ts.map +1 -1
  86. package/dist/auth/bootstrap_routes.js +11 -10
  87. package/dist/auth/cleanup.d.ts +20 -26
  88. package/dist/auth/cleanup.d.ts.map +1 -1
  89. package/dist/auth/cleanup.js +33 -42
  90. package/dist/auth/credential_type_schema.d.ts +115 -0
  91. package/dist/auth/credential_type_schema.d.ts.map +1 -0
  92. package/dist/auth/credential_type_schema.js +127 -0
  93. package/dist/auth/daemon_token_middleware.d.ts +23 -11
  94. package/dist/auth/daemon_token_middleware.d.ts.map +1 -1
  95. package/dist/auth/daemon_token_middleware.js +28 -22
  96. package/dist/auth/ddl.d.ts +2 -2
  97. package/dist/auth/ddl.d.ts.map +1 -1
  98. package/dist/auth/ddl.js +6 -6
  99. package/dist/auth/deps.d.ts +7 -18
  100. package/dist/auth/deps.d.ts.map +1 -1
  101. package/dist/auth/grant_path_schema.d.ts +117 -0
  102. package/dist/auth/grant_path_schema.d.ts.map +1 -0
  103. package/dist/auth/grant_path_schema.js +137 -0
  104. package/dist/auth/invite_queries.d.ts +12 -1
  105. package/dist/auth/invite_queries.d.ts.map +1 -1
  106. package/dist/auth/invite_queries.js +12 -1
  107. package/dist/auth/invite_schema.d.ts +1 -1
  108. package/dist/auth/invite_schema.d.ts.map +1 -1
  109. package/dist/auth/invite_schema.js +1 -1
  110. package/dist/auth/middleware.d.ts.map +1 -1
  111. package/dist/auth/middleware.js +9 -4
  112. package/dist/auth/migrations.d.ts +37 -14
  113. package/dist/auth/migrations.d.ts.map +1 -1
  114. package/dist/auth/migrations.js +79 -32
  115. package/dist/auth/request_context.d.ts +331 -61
  116. package/dist/auth/request_context.d.ts.map +1 -1
  117. package/dist/auth/request_context.js +378 -95
  118. package/dist/auth/{permit_offer_action_specs.d.ts → role_grant_offer_action_specs.d.ts} +163 -94
  119. package/dist/auth/role_grant_offer_action_specs.d.ts.map +1 -0
  120. package/dist/auth/role_grant_offer_action_specs.js +262 -0
  121. package/dist/auth/role_grant_offer_actions.d.ts +104 -0
  122. package/dist/auth/role_grant_offer_actions.d.ts.map +1 -0
  123. package/dist/auth/role_grant_offer_actions.js +473 -0
  124. package/dist/auth/{permit_offer_notifications.d.ts → role_grant_offer_notifications.d.ts} +90 -70
  125. package/dist/auth/role_grant_offer_notifications.d.ts.map +1 -0
  126. package/dist/auth/role_grant_offer_notifications.js +182 -0
  127. package/dist/auth/role_grant_offer_queries.d.ts +242 -0
  128. package/dist/auth/role_grant_offer_queries.d.ts.map +1 -0
  129. package/dist/auth/role_grant_offer_queries.js +533 -0
  130. package/dist/auth/role_grant_offer_schema.d.ts +150 -0
  131. package/dist/auth/role_grant_offer_schema.d.ts.map +1 -0
  132. package/dist/auth/{permit_offer_schema.js → role_grant_offer_schema.js} +60 -36
  133. package/dist/auth/role_grant_queries.d.ts +231 -0
  134. package/dist/auth/role_grant_queries.d.ts.map +1 -0
  135. package/dist/auth/role_grant_queries.js +320 -0
  136. package/dist/auth/role_schema.d.ts +150 -40
  137. package/dist/auth/role_schema.d.ts.map +1 -1
  138. package/dist/auth/role_schema.js +144 -45
  139. package/dist/auth/scope_kind_schema.d.ts +96 -0
  140. package/dist/auth/scope_kind_schema.d.ts.map +1 -0
  141. package/dist/auth/scope_kind_schema.js +94 -0
  142. package/dist/auth/self_service_role_action_specs.d.ts +6 -1
  143. package/dist/auth/self_service_role_action_specs.d.ts.map +1 -1
  144. package/dist/auth/self_service_role_action_specs.js +3 -1
  145. package/dist/auth/self_service_role_actions.d.ts +34 -27
  146. package/dist/auth/self_service_role_actions.d.ts.map +1 -1
  147. package/dist/auth/self_service_role_actions.js +68 -48
  148. package/dist/auth/session_cookie.d.ts +43 -6
  149. package/dist/auth/session_cookie.d.ts.map +1 -1
  150. package/dist/auth/session_cookie.js +31 -5
  151. package/dist/auth/session_middleware.d.ts +37 -3
  152. package/dist/auth/session_middleware.d.ts.map +1 -1
  153. package/dist/auth/session_middleware.js +33 -7
  154. package/dist/auth/signup_routes.d.ts.map +1 -1
  155. package/dist/auth/signup_routes.js +48 -19
  156. package/dist/auth/standard_action_specs.d.ts +2 -2
  157. package/dist/auth/standard_action_specs.js +4 -4
  158. package/dist/auth/standard_rpc_actions.d.ts +23 -19
  159. package/dist/auth/standard_rpc_actions.d.ts.map +1 -1
  160. package/dist/auth/standard_rpc_actions.js +12 -12
  161. package/dist/db/migrate.d.ts +12 -8
  162. package/dist/db/migrate.d.ts.map +1 -1
  163. package/dist/db/migrate.js +10 -7
  164. package/dist/dev/setup.d.ts +2 -2
  165. package/dist/dev/setup.d.ts.map +1 -1
  166. package/dist/dev/setup.js +9 -7
  167. package/dist/env/load.d.ts +1 -1
  168. package/dist/env/load.js +1 -1
  169. package/dist/hono_context.d.ts +64 -5
  170. package/dist/hono_context.d.ts.map +1 -1
  171. package/dist/hono_context.js +38 -2
  172. package/dist/http/CLAUDE.md +264 -87
  173. package/dist/http/auth_shape.d.ts +191 -0
  174. package/dist/http/auth_shape.d.ts.map +1 -0
  175. package/dist/http/auth_shape.js +237 -0
  176. package/dist/http/common_routes.js +3 -3
  177. package/dist/http/db_routes.d.ts +4 -0
  178. package/dist/http/db_routes.d.ts.map +1 -1
  179. package/dist/http/db_routes.js +44 -7
  180. package/dist/http/error_schemas.d.ts +132 -19
  181. package/dist/http/error_schemas.d.ts.map +1 -1
  182. package/dist/http/error_schemas.js +132 -40
  183. package/dist/http/jsonrpc_errors.d.ts +27 -2
  184. package/dist/http/jsonrpc_errors.d.ts.map +1 -1
  185. package/dist/http/jsonrpc_errors.js +26 -2
  186. package/dist/http/pending_effects.d.ts +71 -18
  187. package/dist/http/pending_effects.d.ts.map +1 -1
  188. package/dist/http/pending_effects.js +87 -18
  189. package/dist/http/proxy.d.ts +52 -5
  190. package/dist/http/proxy.d.ts.map +1 -1
  191. package/dist/http/proxy.js +92 -14
  192. package/dist/http/route_spec.d.ts +113 -41
  193. package/dist/http/route_spec.d.ts.map +1 -1
  194. package/dist/http/route_spec.js +130 -52
  195. package/dist/http/schema_helpers.d.ts +3 -2
  196. package/dist/http/schema_helpers.d.ts.map +1 -1
  197. package/dist/http/schema_helpers.js +9 -2
  198. package/dist/http/surface.d.ts +2 -1
  199. package/dist/http/surface.d.ts.map +1 -1
  200. package/dist/http/surface.js +1 -2
  201. package/dist/http/surface_query.d.ts +39 -35
  202. package/dist/http/surface_query.d.ts.map +1 -1
  203. package/dist/http/surface_query.js +79 -36
  204. package/dist/primitive_schemas.d.ts +39 -0
  205. package/dist/primitive_schemas.d.ts.map +1 -0
  206. package/dist/primitive_schemas.js +40 -0
  207. package/dist/realtime/sse_auth_guard.d.ts +5 -5
  208. package/dist/realtime/sse_auth_guard.js +9 -9
  209. package/dist/runtime/mock.d.ts +1 -1
  210. package/dist/runtime/mock.js +1 -1
  211. package/dist/server/app_backend.d.ts +14 -11
  212. package/dist/server/app_backend.d.ts.map +1 -1
  213. package/dist/server/app_backend.js +12 -8
  214. package/dist/server/app_server.d.ts +7 -7
  215. package/dist/server/app_server.d.ts.map +1 -1
  216. package/dist/server/app_server.js +36 -31
  217. package/dist/server/validate_nginx.d.ts +1 -1
  218. package/dist/server/validate_nginx.js +1 -1
  219. package/dist/testing/CLAUDE.md +73 -55
  220. package/dist/testing/admin_integration.d.ts +5 -6
  221. package/dist/testing/admin_integration.d.ts.map +1 -1
  222. package/dist/testing/admin_integration.js +100 -96
  223. package/dist/testing/adversarial_headers.js +1 -1
  224. package/dist/testing/app_server.d.ts +11 -14
  225. package/dist/testing/app_server.d.ts.map +1 -1
  226. package/dist/testing/app_server.js +18 -17
  227. package/dist/testing/assertions.d.ts.map +1 -1
  228. package/dist/testing/assertions.js +2 -1
  229. package/dist/testing/attack_surface.d.ts.map +1 -1
  230. package/dist/testing/attack_surface.js +15 -9
  231. package/dist/testing/audit_completeness.d.ts +2 -2
  232. package/dist/testing/audit_completeness.d.ts.map +1 -1
  233. package/dist/testing/audit_completeness.js +53 -39
  234. package/dist/testing/auth_apps.d.ts +5 -4
  235. package/dist/testing/auth_apps.d.ts.map +1 -1
  236. package/dist/testing/auth_apps.js +28 -22
  237. package/dist/testing/data_exposure.d.ts.map +1 -1
  238. package/dist/testing/data_exposure.js +5 -5
  239. package/dist/testing/db.d.ts +1 -1
  240. package/dist/testing/db.d.ts.map +1 -1
  241. package/dist/testing/db.js +4 -4
  242. package/dist/testing/db_entities.d.ts +22 -0
  243. package/dist/testing/db_entities.d.ts.map +1 -0
  244. package/dist/testing/db_entities.js +28 -0
  245. package/dist/testing/entities.d.ts +10 -8
  246. package/dist/testing/entities.d.ts.map +1 -1
  247. package/dist/testing/entities.js +22 -18
  248. package/dist/testing/integration.d.ts.map +1 -1
  249. package/dist/testing/integration.js +13 -14
  250. package/dist/testing/integration_helpers.d.ts +8 -6
  251. package/dist/testing/integration_helpers.d.ts.map +1 -1
  252. package/dist/testing/integration_helpers.js +29 -23
  253. package/dist/testing/middleware.d.ts +15 -11
  254. package/dist/testing/middleware.d.ts.map +1 -1
  255. package/dist/testing/middleware.js +75 -32
  256. package/dist/testing/rpc_attack_surface.d.ts.map +1 -1
  257. package/dist/testing/rpc_attack_surface.js +40 -24
  258. package/dist/testing/rpc_helpers.d.ts.map +1 -1
  259. package/dist/testing/rpc_helpers.js +3 -1
  260. package/dist/testing/rpc_round_trip.d.ts +1 -1
  261. package/dist/testing/rpc_round_trip.d.ts.map +1 -1
  262. package/dist/testing/rpc_round_trip.js +14 -13
  263. package/dist/testing/sse_round_trip.d.ts +3 -4
  264. package/dist/testing/sse_round_trip.d.ts.map +1 -1
  265. package/dist/testing/sse_round_trip.js +7 -11
  266. package/dist/testing/standard.d.ts +1 -1
  267. package/dist/testing/stubs.d.ts +25 -0
  268. package/dist/testing/stubs.d.ts.map +1 -1
  269. package/dist/testing/stubs.js +43 -2
  270. package/dist/testing/surface_invariants.d.ts +2 -2
  271. package/dist/testing/ws_round_trip.d.ts +12 -13
  272. package/dist/testing/ws_round_trip.d.ts.map +1 -1
  273. package/dist/testing/ws_round_trip.js +24 -12
  274. package/dist/ui/AdminAccounts.svelte +23 -20
  275. package/dist/ui/AdminOverview.svelte +15 -13
  276. package/dist/ui/AdminOverview.svelte.d.ts.map +1 -1
  277. package/dist/ui/{AdminPermitHistory.svelte → AdminRoleGrantHistory.svelte} +12 -12
  278. package/dist/ui/AdminRoleGrantHistory.svelte.d.ts +4 -0
  279. package/dist/ui/AdminRoleGrantHistory.svelte.d.ts.map +1 -0
  280. package/dist/ui/BootstrapForm.svelte +1 -1
  281. package/dist/ui/CLAUDE.md +65 -59
  282. package/dist/ui/{PermitOfferForm.svelte → RoleGrantOfferForm.svelte} +37 -22
  283. package/dist/ui/RoleGrantOfferForm.svelte.d.ts +20 -0
  284. package/dist/ui/RoleGrantOfferForm.svelte.d.ts.map +1 -0
  285. package/dist/ui/{PermitOfferHistory.svelte → RoleGrantOfferHistory.svelte} +12 -12
  286. package/dist/ui/{PermitOfferHistory.svelte.d.ts → RoleGrantOfferHistory.svelte.d.ts} +4 -4
  287. package/dist/ui/RoleGrantOfferHistory.svelte.d.ts.map +1 -0
  288. package/dist/ui/{PermitOfferInbox.svelte → RoleGrantOfferInbox.svelte} +14 -14
  289. package/dist/ui/{PermitOfferInbox.svelte.d.ts → RoleGrantOfferInbox.svelte.d.ts} +4 -4
  290. package/dist/ui/RoleGrantOfferInbox.svelte.d.ts.map +1 -0
  291. package/dist/ui/SignupForm.svelte +1 -1
  292. package/dist/ui/SurfaceExplorer.svelte +35 -15
  293. package/dist/ui/SurfaceExplorer.svelte.d.ts.map +1 -1
  294. package/dist/ui/account_sessions_state.svelte.d.ts +2 -3
  295. package/dist/ui/account_sessions_state.svelte.d.ts.map +1 -1
  296. package/dist/ui/account_sessions_state.svelte.js +2 -3
  297. package/dist/ui/admin_accounts_state.svelte.d.ts +25 -18
  298. package/dist/ui/admin_accounts_state.svelte.d.ts.map +1 -1
  299. package/dist/ui/admin_accounts_state.svelte.js +28 -17
  300. package/dist/ui/admin_rpc_adapters.d.ts +20 -20
  301. package/dist/ui/admin_rpc_adapters.d.ts.map +1 -1
  302. package/dist/ui/admin_rpc_adapters.js +17 -17
  303. package/dist/ui/admin_sessions_state.svelte.d.ts +2 -2
  304. package/dist/ui/admin_sessions_state.svelte.js +2 -2
  305. package/dist/ui/audit_log_state.svelte.d.ts +7 -7
  306. package/dist/ui/audit_log_state.svelte.d.ts.map +1 -1
  307. package/dist/ui/audit_log_state.svelte.js +6 -6
  308. package/dist/ui/auth_state.svelte.d.ts +3 -3
  309. package/dist/ui/auth_state.svelte.d.ts.map +1 -1
  310. package/dist/ui/auth_state.svelte.js +6 -6
  311. package/dist/ui/format_scope.d.ts +2 -2
  312. package/dist/ui/format_scope.js +2 -2
  313. package/dist/ui/{permit_offers_state.svelte.d.ts → role_grant_offers_state.svelte.d.ts} +39 -31
  314. package/dist/ui/role_grant_offers_state.svelte.d.ts.map +1 -0
  315. package/dist/ui/{permit_offers_state.svelte.js → role_grant_offers_state.svelte.js} +25 -19
  316. package/dist/ui/ui_format.js +2 -2
  317. package/package.json +3 -3
  318. package/dist/auth/permit_offer_action_specs.d.ts.map +0 -1
  319. package/dist/auth/permit_offer_action_specs.js +0 -227
  320. package/dist/auth/permit_offer_actions.d.ts +0 -110
  321. package/dist/auth/permit_offer_actions.d.ts.map +0 -1
  322. package/dist/auth/permit_offer_actions.js +0 -452
  323. package/dist/auth/permit_offer_notifications.d.ts.map +0 -1
  324. package/dist/auth/permit_offer_notifications.js +0 -182
  325. package/dist/auth/permit_offer_queries.d.ts +0 -183
  326. package/dist/auth/permit_offer_queries.d.ts.map +0 -1
  327. package/dist/auth/permit_offer_queries.js +0 -408
  328. package/dist/auth/permit_offer_schema.d.ts +0 -103
  329. package/dist/auth/permit_offer_schema.d.ts.map +0 -1
  330. package/dist/auth/permit_queries.d.ts +0 -210
  331. package/dist/auth/permit_queries.d.ts.map +0 -1
  332. package/dist/auth/permit_queries.js +0 -294
  333. package/dist/auth/require_keeper.d.ts +0 -20
  334. package/dist/auth/require_keeper.d.ts.map +0 -1
  335. package/dist/auth/require_keeper.js +0 -35
  336. package/dist/auth/route_guards.d.ts +0 -21
  337. package/dist/auth/route_guards.d.ts.map +0 -1
  338. package/dist/auth/route_guards.js +0 -32
  339. package/dist/auth/session_lifecycle.d.ts +0 -37
  340. package/dist/auth/session_lifecycle.d.ts.map +0 -1
  341. package/dist/auth/session_lifecycle.js +0 -29
  342. package/dist/ui/AdminPermitHistory.svelte.d.ts +0 -4
  343. package/dist/ui/AdminPermitHistory.svelte.d.ts.map +0 -1
  344. package/dist/ui/PermitOfferForm.svelte.d.ts +0 -14
  345. package/dist/ui/PermitOfferForm.svelte.d.ts.map +0 -1
  346. package/dist/ui/PermitOfferHistory.svelte.d.ts.map +0 -1
  347. package/dist/ui/PermitOfferInbox.svelte.d.ts.map +0 -1
  348. package/dist/ui/permit_offers_state.svelte.d.ts.map +0 -1
@@ -1,25 +1,64 @@
1
1
  /**
2
- * Request context middleware and permit checking helpers.
2
+ * Request context middleware and role_grant checking helpers.
3
3
  *
4
- * Builds `{ account, actor, permits }` from a session cookie
5
- * for every authenticated request. Downstream handlers check
6
- * permits, never flags.
4
+ * Two-phase identity resolution:
7
5
  *
8
- * `build_request_context` is the shared helper used by session,
9
- * bearer, and daemon token middleware to resolve account → actor → permits.
10
- * `refresh_permits` reloads permits on an existing context.
6
+ * 1. **Authentication (middleware)** `create_request_context_middleware`,
7
+ * `bearer_auth`, and `daemon_token_middleware` validate the credential
8
+ * (session cookie, bearer token, daemon token) and set `c.var.account_id`
9
+ * + `c.var.credential_type` on the Hono context. They do not resolve
10
+ * an acting actor or load role_grants; `REQUEST_CONTEXT_KEY` stays null at
11
+ * this stage, so account-grain identity is the only thing known.
12
+ * 2. **Authorization (route-spec wrapper / RPC dispatcher)** — after input
13
+ * validation, the per-route layer inspects the route. If the input
14
+ * schema declared `acting?: ActingActor` (reference equality with the
15
+ * canonical `ActingActor` schema) or the auth requires role_grants
16
+ * (`role` / `keeper`), `apply_authorization_phase` resolves the actor
17
+ * against `c.var.account_id` plus the validated `acting` value via
18
+ * `resolve_acting_actor`, builds the `{account, actor, role_grants}`
19
+ * context via `build_request_context`, and sets it on
20
+ * `REQUEST_CONTEXT_KEY` before auth guards fire. Authenticated routes
21
+ * that don't need an actor still get an account-only context via
22
+ * `build_account_context` so handler signatures stay uniform.
23
+ *
24
+ * Account-grain operations (logout, password_change, account_verify,
25
+ * etc.) declare neither `acting` nor role_grant-requiring auth, so no actor
26
+ * is resolved and their handlers see a `RequestContext` with
27
+ * `actor: null` + empty `role_grants`. They never trigger `actor_required`,
28
+ * which is what makes multi-actor logout work without first picking a
29
+ * persona.
30
+ *
31
+ * `build_request_context` loads `account → actor → role_grants` and verifies
32
+ * the `actor.account_id === account.id` binding. `refresh_role_grants`
33
+ * reloads role_grants on an existing context.
11
34
  *
12
35
  * @module
13
36
  */
14
37
  import type { Context, MiddlewareHandler } from 'hono';
15
38
  import type { Logger } from '@fuzdev/fuz_util/log.js';
16
- import { type Account, type Actor, type Permit } from './account_schema.js';
39
+ import { type Account, type Actor, type RoleGrant } from './account_schema.js';
17
40
  import type { QueryDeps } from '../db/query_deps.js';
18
- /** The resolved identity context for an authenticated request. */
41
+ import type { RouteSpec } from '../http/route_spec.js';
42
+ import { type RouteAuth } from '../http/auth_shape.js';
43
+ import { ERROR_ACTOR_REQUIRED, ERROR_ACTOR_NOT_ON_ACCOUNT, ERROR_NO_ACTORS_ON_ACCOUNT, ERROR_ACCOUNT_VANISHED } from '../http/error_schemas.js';
44
+ /**
45
+ * The resolved identity context for an authenticated request.
46
+ *
47
+ * `actor` is null on account-grain routes (no `acting` field on input,
48
+ * no `role` / `keeper` auth) — those handlers don't trigger actor
49
+ * resolution. `role_grants` is empty in that case. Role grant checks
50
+ * (`has_role`, `has_scoped_role`, `has_any_scoped_role`) are
51
+ * null-tolerant on `RequestContext | null`; they additionally treat
52
+ * `actor: null` as "no role_grants" so callers don't have to narrow.
53
+ *
54
+ * Multi-actor invariant: when populated, `actor.account_id === account.id`.
55
+ * `build_request_context` enforces this; the dispatcher's authorization
56
+ * phase rejects with `actor_not_on_account` before reaching the handler.
57
+ */
19
58
  export interface RequestContext {
20
59
  account: Account;
21
- actor: Actor;
22
- permits: Array<Permit>;
60
+ actor: Actor | null;
61
+ role_grants: Array<RoleGrant>;
23
62
  }
24
63
  /** Hono context variable name for the request context. */
25
64
  export declare const REQUEST_CONTEXT_KEY = "request_context";
@@ -43,19 +82,33 @@ export declare const get_request_context: (c: Context) => RequestContext | null;
43
82
  /**
44
83
  * Get the request context, throwing if unauthenticated.
45
84
  *
46
- * Use in route handlers where auth middleware guarantees a context exists
47
- * (i.e., routes with `auth: {type: 'authenticated'}` or stricter).
48
- * Prefer this over `get_request_context(c)!` for explicit error handling.
85
+ * Use in route handlers where the dispatcher's authorization phase guarantees
86
+ * a context exists (i.e., routes with `auth: {type: 'authenticated'}` or
87
+ * stricter). Prefer this over `get_request_context(c)!` for explicit error
88
+ * handling.
49
89
  *
50
90
  * @param c - the Hono context
51
91
  * @returns the request context (never null)
52
- * @throws Error if no request context is set (middleware misconfiguration)
92
+ * @throws Error if no request context is set (dispatcher misconfiguration)
53
93
  */
54
94
  export declare const require_request_context: (c: Context) => RequestContext;
55
95
  /**
56
- * Check if a request context has an active permit for a given role.
96
+ * Request context narrowed to a resolved acting actor.
57
97
  *
58
- * Checks the permits already loaded in the context (no DB query).
98
+ * Used by handlers bound through `rpc_action` against an actor-implying
99
+ * spec (`auth.actor === 'required'`) — the binder's conditional return
100
+ * type tightens `ctx.auth` to this shape because the dispatcher's
101
+ * authorization phase always resolves an actor before the handler runs.
102
+ * The biconditional `actor !== 'none' ⟺ input declares acting?: ActingActor`
103
+ * is enforced at registry time.
104
+ */
105
+ export interface RequestActorContext extends RequestContext {
106
+ actor: Actor;
107
+ }
108
+ /**
109
+ * Check if a request context has an active role_grant for a given role.
110
+ *
111
+ * Checks the role_grants already loaded in the context (no DB query).
59
112
  * Null-tolerant — `null` ctx (unauthenticated) returns `false`. Symmetric
60
113
  * with `has_scoped_role` / `has_any_scoped_role` so the three helpers
61
114
  * compose freely in the same predicate (e.g.
@@ -64,39 +117,43 @@ export declare const require_request_context: (c: Context) => RequestContext;
64
117
  * @param ctx - the request context, or `null` for unauthenticated callers
65
118
  * @param role - the role to check
66
119
  * @param now - current time (defaults to `new Date()`, pass for testability and hot-path efficiency)
67
- * @returns `true` if the actor has an active permit for the role
120
+ * @returns `true` if the actor has an active role_grant for the role
68
121
  */
69
122
  export declare const has_role: (ctx: RequestContext | null, role: string, now?: Date) => boolean;
70
123
  /**
71
- * Whether the request context holds an active permit for `role` at `scope_id`.
124
+ * Whether the request context holds an active role_grant for `role` at `scope_id`.
72
125
  *
73
- * Walks the in-memory `ctx.permits` snapshot loaded once per request by
74
- * `create_request_context_middleware`; zero DB roundtrip per check. The
75
- * "freshness" framing of a SQL re-query is illusory because the race window
76
- * is between predicate and the actual mutation, not predicate and middleware
77
- * load. Closing that race needs a transactional re-check inside the
78
- * UPDATE/INSERT, which neither style provides.
126
+ * Walks the in-memory `ctx.role_grants` snapshot loaded once per request by
127
+ * the route-spec / RPC dispatcher's authorization phase (when the route
128
+ * declares `acting?: ActingActor` or has role_grant-requiring auth); zero DB
129
+ * roundtrip per check. The "freshness" framing of a SQL re-query is
130
+ * illusory because the race window is between predicate and the actual
131
+ * mutation, not predicate and authorization load. Closing that race needs
132
+ * a transactional re-check inside the UPDATE/INSERT, which neither style
133
+ * provides.
79
134
  *
80
- * Null-tolerant — `null` ctx (unauthenticated) returns `false`. Same
81
- * convention as `has_role`; lets the helper drop into `auth: 'public'`
82
- * handlers without a manual narrow. See `cell_authorize` for the
83
- * resource-side analog.
135
+ * Null-tolerant — `null` ctx (unauthenticated) and account-grain
136
+ * contexts (`actor: null`, empty `role_grants`) both return `false`. Same
137
+ * convention as `has_role`; lets the helper drop into public
138
+ * (`{account: 'none', actor: 'none'}`) and account-grain
139
+ * (`{account: 'required', actor: 'none'}`) handlers without a manual
140
+ * narrow. See `cell_authorize` for the resource-side analog.
84
141
  *
85
- * `scope_id` semantics: in-memory `permit.scope_id` is `string | null`, so
142
+ * `scope_id` semantics: in-memory `role_grant.scope_id` is `string | null`, so
86
143
  * JS `===` matches the SQL `IS NOT DISTINCT FROM` semantics exactly:
87
144
  *
88
- * - `scope_id === null` matches global permits (`scope_id IS NULL`).
89
- * - `scope_id === '<uuid>'` matches permits bound to that exact scope.
145
+ * - `scope_id === null` matches global role_grants (`scope_id IS NULL`).
146
+ * - `scope_id === '<uuid>'` matches role_grants bound to that exact scope.
90
147
  *
91
148
  * @param ctx - the request context, or `null` for unauthenticated callers
92
149
  * @param role - the role to check
93
150
  * @param scope_id - the scope to check (`null` for global)
94
151
  * @param now - current time (defaults to `new Date()`, pass for testability and hot-path efficiency)
95
- * @returns `true` iff the actor holds an active permit for the role at the requested scope
152
+ * @returns `true` iff the actor holds an active role_grant for the role at the requested scope
96
153
  */
97
154
  export declare const has_scoped_role: (ctx: RequestContext | null, role: string, scope_id: string | null, now?: Date) => boolean;
98
155
  /**
99
- * Whether the request context holds an active permit for any role in `roles`
156
+ * Whether the request context holds an active role_grant for any role in `roles`
100
157
  * at `scope_id`. Empty `roles` short-circuits to `false` — documents intent
101
158
  * at the call site ("zero roles trivially admit no-one"). Same scope and
102
159
  * null-tolerance semantics as `has_scoped_role`.
@@ -105,66 +162,279 @@ export declare const has_scoped_role: (ctx: RequestContext | null, role: string,
105
162
  * @param roles - the roles that would admit the caller (any-of)
106
163
  * @param scope_id - the scope to check (`null` for global)
107
164
  * @param now - current time (defaults to `new Date()`, pass for testability)
108
- * @returns `true` iff the actor holds an active permit for any role in `roles` at the requested scope
165
+ * @returns `true` iff the actor holds an active role_grant for any role in `roles` at the requested scope
109
166
  */
110
167
  export declare const has_any_scoped_role: (ctx: RequestContext | null, roles: ReadonlyArray<string>, scope_id: string | null, now?: Date) => boolean;
111
168
  /**
112
- * Create middleware that builds the request context from a session cookie.
169
+ * Result of `resolve_acting_actor` either an actor id or a structured
170
+ * error the caller maps to an HTTP response.
171
+ */
172
+ export type ResolveActingActorResult = {
173
+ ok: true;
174
+ actor_id: string;
175
+ } | {
176
+ ok: false;
177
+ reason: 'no_actors';
178
+ } | {
179
+ ok: false;
180
+ reason: 'actor_required';
181
+ available: Array<{
182
+ id: string;
183
+ name: string;
184
+ }>;
185
+ } | {
186
+ ok: false;
187
+ reason: 'actor_not_on_account';
188
+ };
189
+ /**
190
+ * Resolve the acting actor for an authenticated request.
191
+ *
192
+ * Called from the route-spec / RPC dispatcher's authorization phase
193
+ * with the authenticated account id and the validated `acting` value
194
+ * (from the request payload). Applies the uniform resolution rules:
195
+ *
196
+ * - `acting_actor_id` omitted + 1 actor → use it.
197
+ * - `acting_actor_id` omitted + 0 actors → `no_actors` (defensive —
198
+ * signup / bootstrap always create an actor in the same tx, so this
199
+ * is a server error).
200
+ * - `acting_actor_id` omitted + multiple actors → `actor_required` with
201
+ * the available list so the client can prompt; never pick silently.
202
+ * - `acting_actor_id` present + matches an actor on the account → use it.
203
+ * - `acting_actor_id` present + does not match → `actor_not_on_account`.
204
+ * The available list is intentionally not echoed in this branch (treat
205
+ * as opaque rejection).
206
+ *
207
+ * @param deps - query dependencies
208
+ * @param account_id - the authenticated account
209
+ * @param acting_actor_id - the requested acting actor id, or `undefined`
210
+ */
211
+ export declare const resolve_acting_actor: (deps: QueryDeps, account_id: string, acting_actor_id: string | undefined) => Promise<ResolveActingActorResult>;
212
+ /**
213
+ * Create middleware that authenticates the account from a session cookie.
113
214
  *
114
- * Reads the session identity (set by session middleware), looks up
115
- * the `auth_session`, loads account + actor + active permits, and
116
- * sets the `RequestContext` on the Hono context.
215
+ * Reads the session identity (set by session middleware), looks up the
216
+ * `auth_session`, and on a valid session sets `c.var.auth_account_id`,
217
+ * `CREDENTIAL_TYPE_KEY = 'session'`, and `AUTH_SESSION_TOKEN_HASH_KEY`.
218
+ * Touches the session (fire-and-forget). Does not load actor or role_grants;
219
+ * `REQUEST_CONTEXT_KEY` is left null — the route-spec / RPC dispatcher
220
+ * authorization phase resolves the acting actor and builds the full
221
+ * `RequestContext` when the route needs one.
117
222
  *
118
- * If the session is invalid or the account is not found, the context
119
- * is set to `null` (unauthenticated). No 401 is returned — use
120
- * `require_role` or `require_auth` for enforcement.
223
+ * Invalid / missing session leaves all keys null and calls `next()`
224
+ * `require_auth` / `require_role` enforce.
121
225
  *
122
226
  * @param deps - query dependencies (pool-level db for middleware)
123
227
  * @param log - the logger instance
124
228
  * @param session_context_key - the Hono context key where session middleware stored the session token
125
- * @mutates Hono context - sets `REQUEST_CONTEXT_KEY`, `CREDENTIAL_TYPE_KEY`, `AUTH_SESSION_TOKEN_HASH_KEY`, and `AUTH_API_TOKEN_ID_KEY`
229
+ * @mutates Hono context - sets `ACCOUNT_ID_KEY`, `CREDENTIAL_TYPE_KEY`, `AUTH_SESSION_TOKEN_HASH_KEY`, and `AUTH_API_TOKEN_ID_KEY`
126
230
  */
127
231
  export declare const create_request_context_middleware: (deps: QueryDeps, log: Logger, session_context_key?: string) => MiddlewareHandler;
128
232
  /**
129
233
  * Middleware that requires authentication.
130
234
  *
131
- * Returns 401 if no request context is set.
235
+ * Returns 401 if the auth middleware did not set `c.var.auth_account_id`.
132
236
  */
133
237
  export declare const require_auth: MiddlewareHandler;
134
238
  /**
135
- * Create middleware that requires a specific role.
239
+ * Create middleware that requires the actor to hold any of the given
240
+ * roles globally (`scope_id IS NULL`).
241
+ *
242
+ * Returns 401 if unauthenticated, 403 if none of the roles are present.
243
+ * Reads `REQUEST_CONTEXT_KEY` because role-gated routes always run the
244
+ * dispatcher's authorization phase before this guard (the phase sets
245
+ * the actor-bound `RequestContext`).
246
+ *
247
+ * Uses `has_any_scoped_role(ctx, roles, null)` so the gate matches
248
+ * **global / unscoped role_grants only**. A scoped role_grant
249
+ * (`{role: 'admin', scope_id: <some uuid>}`) does not unlock route-spec
250
+ * gates that are inherently global. The same scope-aware check is
251
+ * mirrored in `actions/action_rpc.ts` (HTTP RPC dispatcher) and
252
+ * `actions/register_action_ws.ts` (WS dispatcher) so all three
253
+ * transports agree.
254
+ *
255
+ * Multi-role disjunction (any-of) lets `auth.roles: ['admin', 'steward']`
256
+ * specs translate to one middleware that admits either role. Single-role
257
+ * routes pass `[role_name]`; the array shape is uniform.
258
+ *
259
+ * @param roles - the roles to admit (any-of)
260
+ */
261
+ export declare const require_role: (roles: ReadonlyArray<string>) => MiddlewareHandler;
262
+ /**
263
+ * Create middleware that requires the request's `credential_type` to be
264
+ * one of the given values.
136
265
  *
137
- * Returns 401 if unauthenticated, 403 if the role is missing.
266
+ * Returns 401 if unauthenticated, 403 with
267
+ * `ERROR_CREDENTIAL_TYPE_REQUIRED` + `required_credential_types` echoing
268
+ * the spec's allowlist when the wire-side credential isn't in it.
269
+ * Body shape is symmetric with the role gate (`ERROR_INSUFFICIENT_PERMISSIONS` +
270
+ * `required_roles`) and matches what the RPC dispatcher's post-auth
271
+ * gate emits for the same condition. Today's only credential gate is
272
+ * keeper (`['daemon_token']`); future gates (`agent_token`,
273
+ * `group_actor_token`) reuse this literal and label themselves through
274
+ * the array.
138
275
  *
139
- * @param role - the required role
276
+ * @param credential_types - allowed credential types (any-of)
140
277
  */
141
- export declare const require_role: (role: string) => MiddlewareHandler;
278
+ export declare const require_credential_types: (credential_types: ReadonlyArray<string>) => MiddlewareHandler;
142
279
  /**
143
- * Reload active permits from the database, returning a new request context.
280
+ * Reload active role_grants from the database, returning a new request context.
144
281
  *
145
- * Useful for long-lived WebSocket connections where permits may change
282
+ * Useful for long-lived WebSocket connections where role_grants may change
146
283
  * (grant or revoke) during the connection lifetime. Call periodically
147
284
  * or after receiving a revocation signal.
148
285
  *
149
- * Returns a new `RequestContext` with updated permits — the original
150
- * context is not mutated, making concurrent calls safe.
286
+ * Returns a new `RequestContext` with updated role_grants — the original
287
+ * context is not mutated, making concurrent calls safe. Throws when
288
+ * `ctx.actor` is null; account-grain contexts have no role_grants to refresh.
151
289
  *
152
290
  * @param ctx - the request context to refresh
153
291
  * @param deps - query dependencies
154
- * @returns a new `RequestContext` with fresh permits
292
+ * @returns a new `RequestContext` with fresh role_grants
293
+ * @throws Error when called on an account-grain context (`actor: null`)
155
294
  */
156
- export declare const refresh_permits: (ctx: RequestContext, deps: QueryDeps) => Promise<RequestContext>;
295
+ export declare const refresh_role_grants: (ctx: RequestContext, deps: QueryDeps) => Promise<RequestContext>;
157
296
  /**
158
- * Build a full `RequestContext` from an account id.
297
+ * Build a full `RequestContext` from an account id and an explicit
298
+ * actor id (already resolved via `resolve_acting_actor`).
159
299
  *
160
- * Shared helper used by session, bearer, and daemon token middleware,
161
- * as well as WebSocket upgrade handlers. Does the account actor → permits
162
- * lookup pipeline and returns the composed context, or `null` if
163
- * the account or actor is not found.
300
+ * Loads `account` + the named `actor` + the actor's active role_grants.
301
+ * Verifies the `actor.account_id === account.id` binding so downstream
302
+ * handlers can trust `ctx.actor.account_id === ctx.account.id`. Returns
303
+ * `null` when the account is missing, the actor is missing, or the
304
+ * actor doesn't belong to the supplied account.
305
+ *
306
+ * Called by the route-spec / RPC dispatcher's authorization phase for
307
+ * routes that need an acting actor; account-grain routes use
308
+ * `build_account_context` instead.
164
309
  *
165
310
  * @param deps - query dependencies
166
311
  * @param account_id - the account to build context for
167
- * @returns a request context, or `null` if account/actor not found
312
+ * @param actor_id - the actor this request acts as
313
+ * @returns a request context, or `null` if account/actor not found or mismatched
314
+ */
315
+ export declare const build_request_context: (deps: QueryDeps, account_id: string, actor_id: string) => Promise<RequestActorContext | null>;
316
+ /**
317
+ * Build an account-only `RequestContext` (no actor, no role_grants) from
318
+ * an account id.
319
+ *
320
+ * Used by the dispatcher's authorization phase for authenticated routes
321
+ * that don't need an acting actor — account-grain operations (logout,
322
+ * password change, account self-service). Lets handlers read
323
+ * `auth.account.id` / `auth.account.username` uniformly with role_grant-bound
324
+ * routes; the cost is one extra `query_account_by_id` per request.
325
+ *
326
+ * Returns `null` when the account row is missing (e.g. deleted between
327
+ * the auth middleware's session lookup and the dispatcher) — caller
328
+ * surfaces that as a 500 since it represents a torn read.
329
+ *
330
+ * @param deps - query dependencies
331
+ * @param account_id - the account to build context for
332
+ * @returns an account-only request context, or `null` if the account is missing
333
+ */
334
+ export declare const build_account_context: (deps: QueryDeps, account_id: string) => Promise<RequestContext | null>;
335
+ /**
336
+ * Resolution-failure shape returned by `apply_authorization_phase`. Each
337
+ * transport binds this to the appropriate wire shape — REST emits the body
338
+ * directly via `c.json(body, status)`; the RPC dispatcher folds it into a
339
+ * JSON-RPC error envelope `{jsonrpc, id, error: {code, message, data}}`.
340
+ *
341
+ * The auth phase deliberately stops short of constructing a `Response` so
342
+ * the same failure flows through every transport without the auth-domain
343
+ * code knowing about JSON-RPC. See `fuz_app/CLAUDE.md` § Cleanest
344
+ * architecture takes priority for the rationale.
345
+ */
346
+ export type AuthorizationFailureBody = {
347
+ error: typeof ERROR_ACTOR_REQUIRED;
348
+ available: Array<{
349
+ id: string;
350
+ name: string;
351
+ }>;
352
+ } | {
353
+ error: typeof ERROR_ACTOR_NOT_ON_ACCOUNT;
354
+ } | {
355
+ error: typeof ERROR_NO_ACTORS_ON_ACCOUNT;
356
+ } | {
357
+ error: typeof ERROR_ACCOUNT_VANISHED;
358
+ };
359
+ /**
360
+ * Result of the authorization phase. Pure data — the auth domain stops
361
+ * short of touching the Hono context or producing a `Response` so HTTP
362
+ * RPC, WS, and REST each bind the same shape to their wire surface.
363
+ *
364
+ * - **`{ok: true, request_context}`** — `request_context` is non-null on
365
+ * resolved (actor-bound or account-only) outcomes; `null` for public
366
+ * actions (`{account: 'none', actor: 'none'}`) and for genuine anonymous
367
+ * access on an `'optional'` axis. Public and unauthenticated collapse
368
+ * to the same null `request_context`; every transport already treated
369
+ * them identically.
370
+ * - **`{ok: false, status, body}`** — 400/500 failure. `status` is
371
+ * narrowed to the two values the auth phase emits, so Hono's `c.json`
372
+ * status overload accepts the literals directly. The 500 reasons stay
373
+ * distinct in `body`: `no_actors_on_account` (signup invariant
374
+ * violation); `account_vanished` (torn read after resolve).
375
+ */
376
+ export type AuthorizationResult = {
377
+ ok: true;
378
+ request_context: RequestContext | null;
379
+ } | {
380
+ ok: false;
381
+ status: 400 | 500;
382
+ body: AuthorizationFailureBody;
383
+ };
384
+ /**
385
+ * Apply the dispatcher's authorization phase against the flat-record
386
+ * `RouteAuth` shape. Shared by the route-spec wrapper, the HTTP RPC
387
+ * dispatcher, and the per-message WS dispatcher. Phase order:
388
+ * pre-validation 401 → input validation 400 → authorization phase →
389
+ * post-authorization 403.
390
+ *
391
+ * Pure data — the function does not touch a Hono context. Each transport
392
+ * passes `account_id` (extracted from its own credential surface) and
393
+ * binds the returned `AuthorizationResult` to its wire shape. The REST
394
+ * pipeline additionally writes `REQUEST_CONTEXT_KEY` on `c` for downstream
395
+ * `require_role` / `require_credential_types` middleware that still reads
396
+ * the resolved context off the Hono context.
397
+ *
398
+ * Branching by `auth.account` × `auth.actor`:
399
+ *
400
+ * - Both `'none'` → `{ok: true, request_context: null}`. Public actions
401
+ * never see a `RequestContext`.
402
+ * - `account_id == null` on any non-public route → same null
403
+ * `request_context`. The `'required'` callers were already rejected at
404
+ * the pre-validation gate in the dispatcher; only genuine anonymous
405
+ * access on an `'optional'` axis lands here.
406
+ * - `actor === 'none'` → builds account-only context via
407
+ * `build_account_context`. Null lookup → `account_vanished` 500 failure.
408
+ * - `actor === 'required'` → resolves the actor from `acting_value` (or
409
+ * single-actor account); failures map to 400 / 500.
410
+ * - `actor === 'optional'` → same as `'required'` except multi-actor
411
+ * accounts without an `acting` value fall back to account-only context
412
+ * (no `actor_required` 400). Bad `acting` ids still 400.
413
+ *
414
+ * 500 branches stay distinct: `ERROR_NO_ACTORS_ON_ACCOUNT` (signup
415
+ * invariant violation), `ERROR_ACCOUNT_VANISHED` (torn read after
416
+ * resolve).
417
+ */
418
+ export declare const apply_authorization_phase: (deps: QueryDeps, account_id: string | null, auth: RouteAuth, acting_value: string | undefined) => Promise<AuthorizationResult>;
419
+ /**
420
+ * Create the route-spec authorization handler used by `apply_route_specs`.
421
+ *
422
+ * Reads `acting` off `c.var.validated_input` (or `c.var.validated_query`
423
+ * for GET routes) — input validation runs first, so the authorization
424
+ * phase consumes the typed Zod field instead of pre-parsing the body.
425
+ * Public routes (`auth.account === 'none' && auth.actor === 'none'`)
426
+ * skip the phase entirely.
427
+ *
428
+ * Per registry-time invariant 2, `auth.actor !== 'none'` ⟺ the input
429
+ * (or query) schema declares `acting?: ActingActor` — so reading from
430
+ * `c.var.validated_input.acting` / `c.var.validated_query.acting` is
431
+ * type-safe.
432
+ *
433
+ * Resolved contexts land on `REQUEST_CONTEXT_KEY` so the post-authorization
434
+ * REST middleware (`require_role`, `require_credential_types`) reads the
435
+ * actor-bound context off `c.var`. The HTTP RPC and WS dispatchers consume
436
+ * the `apply_authorization_phase` outcome directly without round-tripping
437
+ * through `c.var`.
168
438
  */
169
- export declare const build_request_context: (deps: QueryDeps, account_id: string) => Promise<RequestContext | null>;
439
+ export declare const create_fuz_authorization_handler: (deps: QueryDeps) => ((c: Context, spec: RouteSpec) => Promise<Response | void>);
170
440
  //# sourceMappingURL=request_context.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"request_context.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/request_context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAC,OAAO,EAAE,iBAAiB,EAAC,MAAM,MAAM,CAAC;AACrD,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AAEpD,OAAO,EAAC,KAAK,OAAO,EAAE,KAAK,KAAK,EAAoB,KAAK,MAAM,EAAC,MAAM,qBAAqB,CAAC;AAQ5F,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,qBAAqB,CAAC;AAOnD,kEAAkE;AAClE,MAAM,WAAW,cAAc;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,KAAK,CAAC;IACb,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;CACvB;AAED,0DAA0D;AAC1D,eAAO,MAAM,mBAAmB,oBAAoB,CAAC;AAErD;;;;;;;;GAQG;AACH,eAAO,MAAM,2BAA2B,4BAA4B,CAAC;AAErE;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,GAAI,GAAG,OAAO,KAAG,cAAc,GAAG,IAEjE,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,uBAAuB,GAAI,GAAG,OAAO,KAAG,cAMpD,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,QAAQ,GACpB,KAAK,cAAc,GAAG,IAAI,EAC1B,MAAM,MAAM,EACZ,MAAK,IAAiB,KACpB,OAAyF,CAAC;AAE7F;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,eAAe,GAC3B,KAAK,cAAc,GAAG,IAAI,EAC1B,MAAM,MAAM,EACZ,UAAU,MAAM,GAAG,IAAI,EACvB,MAAK,IAAiB,KACpB,OAKF,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB,GAC/B,KAAK,cAAc,GAAG,IAAI,EAC1B,OAAO,aAAa,CAAC,MAAM,CAAC,EAC5B,UAAU,MAAM,GAAG,IAAI,EACvB,MAAK,IAAiB,KACpB,OAMF,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,iCAAiC,GAC7C,MAAM,SAAS,EACf,KAAK,MAAM,EACX,4BAAuC,KACrC,iBA6CF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,YAAY,EAAE,iBAM1B,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,GAAI,MAAM,MAAM,KAAG,iBAW3C,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,eAAe,GAC3B,KAAK,cAAc,EACnB,MAAM,SAAS,KACb,OAAO,CAAC,cAAc,CAGxB,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,qBAAqB,GACjC,MAAM,SAAS,EACf,YAAY,MAAM,KAChB,OAAO,CAAC,cAAc,GAAG,IAAI,CAS/B,CAAC"}
1
+ {"version":3,"file":"request_context.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/request_context.ts"],"names":[],"mappings":"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"}