@fuzdev/fuz_app 0.55.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 (331) 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 +56 -34
  174. package/dist/http/error_schemas.d.ts.map +1 -1
  175. package/dist/http/error_schemas.js +63 -28
  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 +2 -2
  258. package/dist/testing/ws_round_trip.d.ts +12 -13
  259. package/dist/testing/ws_round_trip.d.ts.map +1 -1
  260. package/dist/testing/ws_round_trip.js +19 -11
  261. package/dist/ui/AdminAccounts.svelte +23 -20
  262. package/dist/ui/AdminOverview.svelte +15 -13
  263. package/dist/ui/AdminOverview.svelte.d.ts.map +1 -1
  264. package/dist/ui/{AdminPermitHistory.svelte → AdminRoleGrantHistory.svelte} +12 -12
  265. package/dist/ui/AdminRoleGrantHistory.svelte.d.ts +4 -0
  266. package/dist/ui/AdminRoleGrantHistory.svelte.d.ts.map +1 -0
  267. package/dist/ui/BootstrapForm.svelte +1 -1
  268. package/dist/ui/CLAUDE.md +60 -60
  269. package/dist/ui/{PermitOfferForm.svelte → RoleGrantOfferForm.svelte} +27 -26
  270. package/dist/ui/{PermitOfferForm.svelte.d.ts → RoleGrantOfferForm.svelte.d.ts} +7 -7
  271. package/dist/ui/RoleGrantOfferForm.svelte.d.ts.map +1 -0
  272. package/dist/ui/{PermitOfferHistory.svelte → RoleGrantOfferHistory.svelte} +12 -12
  273. package/dist/ui/{PermitOfferHistory.svelte.d.ts → RoleGrantOfferHistory.svelte.d.ts} +4 -4
  274. package/dist/ui/RoleGrantOfferHistory.svelte.d.ts.map +1 -0
  275. package/dist/ui/{PermitOfferInbox.svelte → RoleGrantOfferInbox.svelte} +14 -14
  276. package/dist/ui/{PermitOfferInbox.svelte.d.ts → RoleGrantOfferInbox.svelte.d.ts} +4 -4
  277. package/dist/ui/RoleGrantOfferInbox.svelte.d.ts.map +1 -0
  278. package/dist/ui/SignupForm.svelte +1 -1
  279. package/dist/ui/SurfaceExplorer.svelte +35 -15
  280. package/dist/ui/SurfaceExplorer.svelte.d.ts.map +1 -1
  281. package/dist/ui/account_sessions_state.svelte.d.ts +2 -3
  282. package/dist/ui/account_sessions_state.svelte.d.ts.map +1 -1
  283. package/dist/ui/account_sessions_state.svelte.js +2 -3
  284. package/dist/ui/admin_accounts_state.svelte.d.ts +18 -18
  285. package/dist/ui/admin_accounts_state.svelte.d.ts.map +1 -1
  286. package/dist/ui/admin_accounts_state.svelte.js +16 -16
  287. package/dist/ui/admin_rpc_adapters.d.ts +20 -20
  288. package/dist/ui/admin_rpc_adapters.d.ts.map +1 -1
  289. package/dist/ui/admin_rpc_adapters.js +17 -17
  290. package/dist/ui/admin_sessions_state.svelte.d.ts +2 -2
  291. package/dist/ui/admin_sessions_state.svelte.js +2 -2
  292. package/dist/ui/audit_log_state.svelte.d.ts +7 -7
  293. package/dist/ui/audit_log_state.svelte.d.ts.map +1 -1
  294. package/dist/ui/audit_log_state.svelte.js +6 -6
  295. package/dist/ui/auth_state.svelte.d.ts +3 -3
  296. package/dist/ui/auth_state.svelte.d.ts.map +1 -1
  297. package/dist/ui/auth_state.svelte.js +6 -6
  298. package/dist/ui/format_scope.d.ts +2 -2
  299. package/dist/ui/format_scope.js +2 -2
  300. package/dist/ui/{permit_offers_state.svelte.d.ts → role_grant_offers_state.svelte.d.ts} +30 -30
  301. package/dist/ui/role_grant_offers_state.svelte.d.ts.map +1 -0
  302. package/dist/ui/{permit_offers_state.svelte.js → role_grant_offers_state.svelte.js} +18 -18
  303. package/dist/ui/ui_format.js +2 -2
  304. package/package.json +3 -3
  305. package/dist/auth/permit_offer_action_specs.d.ts.map +0 -1
  306. package/dist/auth/permit_offer_action_specs.js +0 -258
  307. package/dist/auth/permit_offer_actions.d.ts +0 -110
  308. package/dist/auth/permit_offer_actions.d.ts.map +0 -1
  309. package/dist/auth/permit_offer_notifications.d.ts.map +0 -1
  310. package/dist/auth/permit_offer_notifications.js +0 -182
  311. package/dist/auth/permit_offer_queries.d.ts.map +0 -1
  312. package/dist/auth/permit_offer_schema.d.ts +0 -125
  313. package/dist/auth/permit_offer_schema.d.ts.map +0 -1
  314. package/dist/auth/permit_queries.d.ts +0 -222
  315. package/dist/auth/permit_queries.d.ts.map +0 -1
  316. package/dist/auth/permit_queries.js +0 -305
  317. package/dist/auth/require_keeper.d.ts +0 -20
  318. package/dist/auth/require_keeper.d.ts.map +0 -1
  319. package/dist/auth/require_keeper.js +0 -35
  320. package/dist/auth/route_guards.d.ts +0 -27
  321. package/dist/auth/route_guards.d.ts.map +0 -1
  322. package/dist/auth/route_guards.js +0 -38
  323. package/dist/auth/session_lifecycle.d.ts +0 -37
  324. package/dist/auth/session_lifecycle.d.ts.map +0 -1
  325. package/dist/auth/session_lifecycle.js +0 -29
  326. package/dist/ui/AdminPermitHistory.svelte.d.ts +0 -4
  327. package/dist/ui/AdminPermitHistory.svelte.d.ts.map +0 -1
  328. package/dist/ui/PermitOfferForm.svelte.d.ts.map +0 -1
  329. package/dist/ui/PermitOfferHistory.svelte.d.ts.map +0 -1
  330. package/dist/ui/PermitOfferInbox.svelte.d.ts.map +0 -1
  331. package/dist/ui/permit_offers_state.svelte.d.ts.map +0 -1
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Request context middleware and permit checking helpers.
2
+ * Request context middleware and role_grant checking helpers.
3
3
  *
4
4
  * Two-phase identity resolution:
5
5
  *
@@ -7,50 +7,49 @@
7
7
  * `bearer_auth`, and `daemon_token_middleware` validate the credential
8
8
  * (session cookie, bearer token, daemon token) and set `c.var.account_id`
9
9
  * + `c.var.credential_type` on the Hono context. They do not resolve
10
- * an acting actor or load permits; `REQUEST_CONTEXT_KEY` stays null at
10
+ * an acting actor or load role_grants; `REQUEST_CONTEXT_KEY` stays null at
11
11
  * this stage, so account-grain identity is the only thing known.
12
12
  * 2. **Authorization (route-spec wrapper / RPC dispatcher)** — after input
13
13
  * validation, the per-route layer inspects the route. If the input
14
14
  * schema declared `acting?: ActingActor` (reference equality with the
15
- * canonical `ActingActor` schema) or the auth requires permits
15
+ * canonical `ActingActor` schema) or the auth requires role_grants
16
16
  * (`role` / `keeper`), `apply_authorization_phase` resolves the actor
17
17
  * against `c.var.account_id` plus the validated `acting` value via
18
- * `resolve_acting_actor`, builds the `{account, actor, permits}`
18
+ * `resolve_acting_actor`, builds the `{account, actor, role_grants}`
19
19
  * context via `build_request_context`, and sets it on
20
20
  * `REQUEST_CONTEXT_KEY` before auth guards fire. Authenticated routes
21
21
  * that don't need an actor still get an account-only context via
22
22
  * `build_account_context` so handler signatures stay uniform.
23
23
  *
24
24
  * Account-grain operations (logout, password_change, account_verify,
25
- * etc.) declare neither `acting` nor permit-requiring auth, so no actor
25
+ * etc.) declare neither `acting` nor role_grant-requiring auth, so no actor
26
26
  * is resolved and their handlers see a `RequestContext` with
27
- * `actor: null` + empty `permits`. They never trigger `actor_required`,
27
+ * `actor: null` + empty `role_grants`. They never trigger `actor_required`,
28
28
  * which is what makes multi-actor logout work without first picking a
29
29
  * persona.
30
30
  *
31
- * `build_request_context` loads `account → actor → permits` and verifies
32
- * the `actor.account_id === account.id` binding. `refresh_permits`
33
- * reloads permits on an existing context.
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.
34
34
  *
35
35
  * @module
36
36
  */
37
37
  import type { Context, MiddlewareHandler } from 'hono';
38
- import { z } from 'zod';
39
38
  import type { Logger } from '@fuzdev/fuz_util/log.js';
40
- import { type Account, type Actor, type Permit } from './account_schema.js';
39
+ import { type Account, type Actor, type RoleGrant } from './account_schema.js';
41
40
  import type { QueryDeps } from '../db/query_deps.js';
42
- import type { ActionAuth } from '../actions/action_spec.js';
43
- import type { RouteAuth, RouteSpec } from '../http/route_spec.js';
41
+ import type { RouteSpec } from '../http/route_spec.js';
42
+ import { type RouteAuth } from '../http/auth_shape.js';
44
43
  import { ERROR_ACTOR_REQUIRED, ERROR_ACTOR_NOT_ON_ACCOUNT, ERROR_NO_ACTORS_ON_ACCOUNT, ERROR_ACCOUNT_VANISHED } from '../http/error_schemas.js';
45
44
  /**
46
45
  * The resolved identity context for an authenticated request.
47
46
  *
48
47
  * `actor` is null on account-grain routes (no `acting` field on input,
49
48
  * no `role` / `keeper` auth) — those handlers don't trigger actor
50
- * resolution. `permits` is empty in that case. Permit checks
49
+ * resolution. `role_grants` is empty in that case. Role grant checks
51
50
  * (`has_role`, `has_scoped_role`, `has_any_scoped_role`) are
52
51
  * null-tolerant on `RequestContext | null`; they additionally treat
53
- * `actor: null` as "no permits" so callers don't have to narrow.
52
+ * `actor: null` as "no role_grants" so callers don't have to narrow.
54
53
  *
55
54
  * Multi-actor invariant: when populated, `actor.account_id === account.id`.
56
55
  * `build_request_context` enforces this; the dispatcher's authorization
@@ -59,7 +58,7 @@ import { ERROR_ACTOR_REQUIRED, ERROR_ACTOR_NOT_ON_ACCOUNT, ERROR_NO_ACTORS_ON_AC
59
58
  export interface RequestContext {
60
59
  account: Account;
61
60
  actor: Actor | null;
62
- permits: Array<Permit>;
61
+ role_grants: Array<RoleGrant>;
63
62
  }
64
63
  /** Hono context variable name for the request context. */
65
64
  export declare const REQUEST_CONTEXT_KEY = "request_context";
@@ -96,39 +95,20 @@ export declare const require_request_context: (c: Context) => RequestContext;
96
95
  /**
97
96
  * Request context narrowed to a resolved acting actor.
98
97
  *
99
- * Returned by `require_request_actor` for handlers whose route resolves
100
- * an actor actions with `auth: 'keeper' | {role}` or with input that
101
- * declares `acting?: ActingActor`. Lets handlers drop the `auth.actor!`
102
- * non-null assertion that was masking the dispatcher invariant.
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.
103
104
  */
104
105
  export interface RequestActorContext extends RequestContext {
105
106
  actor: Actor;
106
107
  }
107
108
  /**
108
- * Narrow `RequestContext | null` to a non-null context (auth invariant).
109
+ * Check if a request context has an active role_grant for a given role.
109
110
  *
110
- * Use in RPC action handlers whose spec is non-public the dispatcher's
111
- * pre-validation auth gate has already short-circuited unauthenticated
112
- * callers, so `ctx.auth` is non-null by the time the handler runs.
113
- *
114
- * @throws Error when called from a public-auth handler (programmer error)
115
- */
116
- export declare const require_request_auth: (auth: RequestContext | null) => RequestContext;
117
- /**
118
- * Narrow `RequestContext | null` to `RequestActorContext` (actor invariant).
119
- *
120
- * Use in RPC action handlers whose spec declares `auth: 'keeper' | {role}`
121
- * or whose input declares `acting?: ActingActor` — the dispatcher's
122
- * authorization phase resolves an actor before the handler runs. Replaces
123
- * the `ctx.auth!.actor!.id` chain that the type system can't otherwise see.
124
- *
125
- * @throws Error when the handler runs without actor resolution (programmer error)
126
- */
127
- export declare const require_request_actor: (auth: RequestContext | null) => RequestActorContext;
128
- /**
129
- * Check if a request context has an active permit for a given role.
130
- *
131
- * Checks the permits already loaded in the context (no DB query).
111
+ * Checks the role_grants already loaded in the context (no DB query).
132
112
  * Null-tolerant — `null` ctx (unauthenticated) returns `false`. Symmetric
133
113
  * with `has_scoped_role` / `has_any_scoped_role` so the three helpers
134
114
  * compose freely in the same predicate (e.g.
@@ -137,15 +117,15 @@ export declare const require_request_actor: (auth: RequestContext | null) => Req
137
117
  * @param ctx - the request context, or `null` for unauthenticated callers
138
118
  * @param role - the role to check
139
119
  * @param now - current time (defaults to `new Date()`, pass for testability and hot-path efficiency)
140
- * @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
141
121
  */
142
122
  export declare const has_role: (ctx: RequestContext | null, role: string, now?: Date) => boolean;
143
123
  /**
144
- * 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`.
145
125
  *
146
- * Walks the in-memory `ctx.permits` snapshot loaded once per request by
126
+ * Walks the in-memory `ctx.role_grants` snapshot loaded once per request by
147
127
  * the route-spec / RPC dispatcher's authorization phase (when the route
148
- * declares `acting?: ActingActor` or has permit-requiring auth); zero DB
128
+ * declares `acting?: ActingActor` or has role_grant-requiring auth); zero DB
149
129
  * roundtrip per check. The "freshness" framing of a SQL re-query is
150
130
  * illusory because the race window is between predicate and the actual
151
131
  * mutation, not predicate and authorization load. Closing that race needs
@@ -153,26 +133,27 @@ export declare const has_role: (ctx: RequestContext | null, role: string, now?:
153
133
  * provides.
154
134
  *
155
135
  * Null-tolerant — `null` ctx (unauthenticated) and account-grain
156
- * contexts (`actor: null`, empty `permits`) both return `false`. Same
157
- * convention as `has_role`; lets the helper drop into `auth: 'public'`
158
- * or account-grain handlers without a manual narrow. See `cell_authorize`
159
- * for the resource-side analog.
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.
160
141
  *
161
- * `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
162
143
  * JS `===` matches the SQL `IS NOT DISTINCT FROM` semantics exactly:
163
144
  *
164
- * - `scope_id === null` matches global permits (`scope_id IS NULL`).
165
- * - `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.
166
147
  *
167
148
  * @param ctx - the request context, or `null` for unauthenticated callers
168
149
  * @param role - the role to check
169
150
  * @param scope_id - the scope to check (`null` for global)
170
151
  * @param now - current time (defaults to `new Date()`, pass for testability and hot-path efficiency)
171
- * @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
172
153
  */
173
154
  export declare const has_scoped_role: (ctx: RequestContext | null, role: string, scope_id: string | null, now?: Date) => boolean;
174
155
  /**
175
- * 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`
176
157
  * at `scope_id`. Empty `roles` short-circuits to `false` — documents intent
177
158
  * at the call site ("zero roles trivially admit no-one"). Same scope and
178
159
  * null-tolerance semantics as `has_scoped_role`.
@@ -181,7 +162,7 @@ export declare const has_scoped_role: (ctx: RequestContext | null, role: string,
181
162
  * @param roles - the roles that would admit the caller (any-of)
182
163
  * @param scope_id - the scope to check (`null` for global)
183
164
  * @param now - current time (defaults to `new Date()`, pass for testability)
184
- * @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
185
166
  */
186
167
  export declare const has_any_scoped_role: (ctx: RequestContext | null, roles: ReadonlyArray<string>, scope_id: string | null, now?: Date) => boolean;
187
168
  /**
@@ -234,7 +215,7 @@ export declare const resolve_acting_actor: (deps: QueryDeps, account_id: string,
234
215
  * Reads the session identity (set by session middleware), looks up the
235
216
  * `auth_session`, and on a valid session sets `c.var.auth_account_id`,
236
217
  * `CREDENTIAL_TYPE_KEY = 'session'`, and `AUTH_SESSION_TOKEN_HASH_KEY`.
237
- * Touches the session (fire-and-forget). Does not load actor or permits;
218
+ * Touches the session (fire-and-forget). Does not load actor or role_grants;
238
219
  * `REQUEST_CONTEXT_KEY` is left null — the route-spec / RPC dispatcher
239
220
  * authorization phase resolves the acting actor and builds the full
240
221
  * `RequestContext` when the route needs one.
@@ -255,38 +236,68 @@ export declare const create_request_context_middleware: (deps: QueryDeps, log: L
255
236
  */
256
237
  export declare const require_auth: MiddlewareHandler;
257
238
  /**
258
- * Create middleware that requires a specific role.
259
- *
260
- * Returns 401 if unauthenticated, 403 if the role is missing. Reads
261
- * `REQUEST_CONTEXT_KEY` because role-gated routes always run the
262
- * dispatcher's authorization phase before this guard (the phase sets the
263
- * actor-bound `RequestContext`).
264
- *
265
- * @param role - the required 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)
266
260
  */
267
- export declare const require_role: (role: string) => MiddlewareHandler;
261
+ export declare const require_role: (roles: ReadonlyArray<string>) => MiddlewareHandler;
268
262
  /**
269
- * Reload active permits from the database, returning a new request context.
263
+ * Create middleware that requires the request's `credential_type` to be
264
+ * one of the given values.
265
+ *
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.
275
+ *
276
+ * @param credential_types - allowed credential types (any-of)
277
+ */
278
+ export declare const require_credential_types: (credential_types: ReadonlyArray<string>) => MiddlewareHandler;
279
+ /**
280
+ * Reload active role_grants from the database, returning a new request context.
270
281
  *
271
- * Useful for long-lived WebSocket connections where permits may change
282
+ * Useful for long-lived WebSocket connections where role_grants may change
272
283
  * (grant or revoke) during the connection lifetime. Call periodically
273
284
  * or after receiving a revocation signal.
274
285
  *
275
- * Returns a new `RequestContext` with updated permits — the original
286
+ * Returns a new `RequestContext` with updated role_grants — the original
276
287
  * context is not mutated, making concurrent calls safe. Throws when
277
- * `ctx.actor` is null; account-grain contexts have no permits to refresh.
288
+ * `ctx.actor` is null; account-grain contexts have no role_grants to refresh.
278
289
  *
279
290
  * @param ctx - the request context to refresh
280
291
  * @param deps - query dependencies
281
- * @returns a new `RequestContext` with fresh permits
292
+ * @returns a new `RequestContext` with fresh role_grants
282
293
  * @throws Error when called on an account-grain context (`actor: null`)
283
294
  */
284
- export declare const refresh_permits: (ctx: RequestContext, deps: QueryDeps) => Promise<RequestContext>;
295
+ export declare const refresh_role_grants: (ctx: RequestContext, deps: QueryDeps) => Promise<RequestContext>;
285
296
  /**
286
297
  * Build a full `RequestContext` from an account id and an explicit
287
298
  * actor id (already resolved via `resolve_acting_actor`).
288
299
  *
289
- * Loads `account` + the named `actor` + the actor's active permits.
300
+ * Loads `account` + the named `actor` + the actor's active role_grants.
290
301
  * Verifies the `actor.account_id === account.id` binding so downstream
291
302
  * handlers can trust `ctx.actor.account_id === ctx.account.id`. Returns
292
303
  * `null` when the account is missing, the actor is missing, or the
@@ -303,13 +314,13 @@ export declare const refresh_permits: (ctx: RequestContext, deps: QueryDeps) =>
303
314
  */
304
315
  export declare const build_request_context: (deps: QueryDeps, account_id: string, actor_id: string) => Promise<RequestActorContext | null>;
305
316
  /**
306
- * Build an account-only `RequestContext` (no actor, no permits) from
317
+ * Build an account-only `RequestContext` (no actor, no role_grants) from
307
318
  * an account id.
308
319
  *
309
320
  * Used by the dispatcher's authorization phase for authenticated routes
310
321
  * that don't need an acting actor — account-grain operations (logout,
311
322
  * password change, account self-service). Lets handlers read
312
- * `auth.account.id` / `auth.account.username` uniformly with permit-bound
323
+ * `auth.account.id` / `auth.account.username` uniformly with role_grant-bound
313
324
  * routes; the cost is one extra `query_account_by_id` per request.
314
325
  *
315
326
  * Returns `null` when the account row is missing (e.g. deleted between
@@ -321,41 +332,6 @@ export declare const build_request_context: (deps: QueryDeps, account_id: string
321
332
  * @returns an account-only request context, or `null` if the account is missing
322
333
  */
323
334
  export declare const build_account_context: (deps: QueryDeps, account_id: string) => Promise<RequestContext | null>;
324
- /**
325
- * Whether the supplied auth descriptor implies an acting actor must be
326
- * resolved (i.e., permit-requiring auth: `'role'` or `'keeper'`).
327
- *
328
- * The dispatcher's authorization phase uses this to decide whether to
329
- * walk the actor list when the input schema doesn't already declare
330
- * `acting?: ActingActor`. Accepts either auth shape — the route-spec
331
- * `RouteAuth` (`{type: 'role' | 'keeper' | ...}`) or the action-spec
332
- * `ActionAuth` (`'keeper' | {role}`) — so HTTP and RPC dispatchers share
333
- * one source of truth for the "permit-bound" rule.
334
- */
335
- export declare const is_actor_implying_auth: (auth: RouteAuth | ActionAuth) => boolean;
336
- /**
337
- * Whether an input schema declares the canonical `acting?: ActingActor`
338
- * field. Reference-equality on the exported `ActingActor` schema —
339
- * consumer schemas with unrelated `acting` fields don't trip this check.
340
- *
341
- * Peels through Zod wrappers (`optional`, `nullable`, `default`,
342
- * `transform`, `pipe`, `prefault`) via `zod_unwrap_to_object` so a spec
343
- * authored as `z.optional(z.strictObject({acting: ActingActor}))` or
344
- * `z.strictObject({acting: ActingActor}).default({})` still trips the
345
- * predicate. The wrapper-tolerant lookup is defense-in-depth — the
346
- * canonical shape is the un-wrapped `z.strictObject({acting: ActingActor})`,
347
- * but variant B in `~/dev/grimoire/lore/fuz_app/TODO_PUBLIC_AUTH_PHASE.md`
348
- * makes this predicate authorization-correctness load-bearing for
349
- * `auth: 'public'` actions, so missing a wrapper-bound declaration
350
- * would silently skip actor resolution. The reference-equality check
351
- * on `ActingActor` keeps consumer schemas with unrelated `acting`
352
- * fields from tripping the predicate even after the wrapper peel.
353
- *
354
- * The dispatcher's authorization phase uses this to decide whether to
355
- * pull the actor id from validated input (so multi-actor users can pick
356
- * a persona on actor-needing routes).
357
- */
358
- export declare const input_schema_declares_acting: (schema: z.ZodType) => boolean;
359
335
  /**
360
336
  * Resolution-failure shape returned by `apply_authorization_phase`. Each
361
337
  * transport binds this to the appropriate wire shape — REST emits the body
@@ -381,73 +357,84 @@ export type AuthorizationFailureBody = {
381
357
  error: typeof ERROR_ACCOUNT_VANISHED;
382
358
  };
383
359
  /**
384
- * A `(status, body)` pair the caller binds to a transport-shaped response.
385
- * `status` is narrowed to the two values the auth phase emits Hono's
386
- * `c.json` status overload accepts the literals directly, and downstream
387
- * binders avoid casts they would otherwise need against a `number`.
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).
388
375
  */
389
- export interface AuthorizationFailure {
376
+ export type AuthorizationResult = {
377
+ ok: true;
378
+ request_context: RequestContext | null;
379
+ } | {
380
+ ok: false;
390
381
  status: 400 | 500;
391
382
  body: AuthorizationFailureBody;
392
- }
383
+ };
393
384
  /**
394
- * Apply the dispatcher's authorization phase. Shared by the route-spec
395
- * wrapper and the RPC dispatcher.
396
- *
397
- * - When `c.var.auth_account_id` is `null`, returns `void` so the
398
- * downstream auth guard can fire 401 (less-helpful than `actor_required`
399
- * for the unauthenticated case).
400
- * - When `needs_actor` is true, resolves the actor against the account
401
- * plus the supplied `acting` value, then builds the full
402
- * `{account, actor, permits}` context.
403
- * - When `needs_actor` is false, builds an account-only context so
404
- * handler signatures stay uniform across the surface.
405
- *
406
- * On resolution failure returns an `AuthorizationFailure` (`{status, body}`)
407
- * the caller wraps in a transport-appropriate response. Three 500 branches
408
- * are kept distinct so the wire shape names what actually went wrong:
409
- *
410
- * - 500 `ERROR_NO_ACTORS_ON_ACCOUNT` — `resolve_acting_actor` returned
411
- * `no_actors`. The actor enumeration succeeded and came back empty;
412
- * signup / bootstrap should have created one in the same transaction,
413
- * so this is a real corruption signal.
414
- * - 500 `ERROR_ACCOUNT_VANISHED` `build_request_context` /
415
- * `build_account_context` returned null after a successful
416
- * `resolve_acting_actor`. The account or actor row was deleted between
417
- * the credential check and authorization (torn read race), or in
418
- * the `build_request_context` actor↔account mismatch sub-branch the
419
- * binding flipped under us. Reachability of the mismatch sub-branch in
420
- * production is essentially zero (`resolve_acting_actor` already
421
- * verified the actor was on this account, and `actor.account_id` only
422
- * changes via row-level edits no production path makes), so collapsing
423
- * that case into the torn-read shape costs nothing.
424
- *
425
- * Other failure paths: 400 `ERROR_ACTOR_REQUIRED` / `ERROR_ACTOR_NOT_ON_ACCOUNT`.
426
- * Returns `undefined` on success.
427
- *
428
- * @mutates Hono context - sets `REQUEST_CONTEXT_KEY` on success
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).
429
417
  */
430
- export declare const apply_authorization_phase: (deps: QueryDeps, c: Context, needs_actor: boolean, acting_value: string | undefined) => Promise<AuthorizationFailure | void>;
418
+ export declare const apply_authorization_phase: (deps: QueryDeps, account_id: string | null, auth: RouteAuth, acting_value: string | undefined) => Promise<AuthorizationResult>;
431
419
  /**
432
420
  * Create the route-spec authorization handler used by `apply_route_specs`.
433
421
  *
434
- * Decides whether the route needs actor resolution from `spec.auth` plus
435
- * `spec.input` introspection, extracts the raw `acting` value (string
436
- * typeguard, no schema validation), and delegates to
437
- * `apply_authorization_phase`. Public routes (`auth.type === 'none'`) skip
438
- * the phase entirely; their handlers see no `RequestContext`.
439
- *
440
- * Authorization runs before input validation (matches the RPC dispatcher's
441
- * order). For GET routes `acting` comes from the URL query string; for
442
- * mutating methods it comes from a pre-parse of the JSON body. The pre-
443
- * parse result lands on `c.var.cached_request_body` so the subsequent
444
- * `create_input_validation` step reads the parsed value from there
445
- * without re-running `JSON.parse` explicit cache, independent of
446
- * Hono's internal `bodyCache` behavior. A malformed body fails the
447
- * pre-parse silently (`acting` treated as undefined, cache flagged
448
- * `{ok: false}`) and is then rejected with `ERROR_INVALID_JSON_BODY`
449
- * by the input-validation step that reads the failure flag — producing
450
- * the same final response as if the validation step had parsed first.
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`.
451
438
  */
452
439
  export declare const create_fuz_authorization_handler: (deps: QueryDeps) => ((c: Context, spec: RouteSpec) => Promise<Response | void>);
453
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":"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"}
1
+ {"version":3,"file":"request_context.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/request_context.ts"],"names":[],"mappings":"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"}