@fuzdev/fuz_app 0.147.0 → 0.149.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 (303) hide show
  1. package/dist/actions/CLAUDE.md +8 -6
  2. package/dist/actions/action_codegen.d.ts +15 -1
  3. package/dist/actions/action_codegen.d.ts.map +1 -1
  4. package/dist/actions/action_codegen.js +23 -2
  5. package/dist/actions/action_event.d.ts.map +1 -1
  6. package/dist/actions/action_event.js +14 -1
  7. package/dist/actions/perform_action.d.ts +17 -1
  8. package/dist/actions/perform_action.d.ts.map +1 -1
  9. package/dist/actions/perform_action.js +23 -3
  10. package/dist/auth/CLAUDE.md +3 -2
  11. package/dist/auth/account_action_specs.d.ts +12 -0
  12. package/dist/auth/account_action_specs.d.ts.map +1 -1
  13. package/dist/auth/account_action_specs.js +16 -2
  14. package/dist/auth/account_actions.d.ts.map +1 -1
  15. package/dist/auth/account_actions.js +7 -4
  16. package/dist/auth/admin_action_specs.d.ts.map +1 -1
  17. package/dist/auth/admin_action_specs.js +29 -8
  18. package/dist/auth/audit_emitter.d.ts +14 -0
  19. package/dist/auth/audit_emitter.d.ts.map +1 -1
  20. package/dist/auth/audit_emitter.js +5 -1
  21. package/dist/auth/cell_action_specs.d.ts +3 -1
  22. package/dist/auth/cell_action_specs.d.ts.map +1 -1
  23. package/dist/auth/cell_action_specs.js +5 -5
  24. package/dist/auth/cell_actions.d.ts.map +1 -1
  25. package/dist/auth/cell_actions.js +2 -3
  26. package/dist/auth/cell_data_schema.d.ts +1 -1
  27. package/dist/auth/cell_data_schema.js +1 -1
  28. package/dist/auth/cell_field_action_specs.d.ts +4 -3
  29. package/dist/auth/cell_field_action_specs.d.ts.map +1 -1
  30. package/dist/auth/cell_field_action_specs.js +5 -6
  31. package/dist/auth/cell_field_actions.d.ts.map +1 -1
  32. package/dist/auth/cell_field_actions.js +8 -1
  33. package/dist/auth/cell_item_action_specs.d.ts +4 -2
  34. package/dist/auth/cell_item_action_specs.d.ts.map +1 -1
  35. package/dist/auth/cell_item_action_specs.js +5 -5
  36. package/dist/auth/cell_item_actions.d.ts.map +1 -1
  37. package/dist/auth/cell_item_actions.js +8 -1
  38. package/dist/auth/role_grant_offer_action_specs.d.ts +2 -0
  39. package/dist/auth/role_grant_offer_action_specs.d.ts.map +1 -1
  40. package/dist/auth/role_grant_offer_action_specs.js +8 -4
  41. package/dist/http/CLAUDE.md +14 -2
  42. package/dist/http/error_schemas.d.ts +8 -0
  43. package/dist/http/error_schemas.d.ts.map +1 -1
  44. package/dist/http/error_schemas.js +12 -0
  45. package/dist/http/jsonrpc_errors.d.ts +40 -15
  46. package/dist/http/jsonrpc_errors.d.ts.map +1 -1
  47. package/dist/http/jsonrpc_errors.js +90 -35
  48. package/dist/primitive_schemas.d.ts +1 -1
  49. package/dist/primitive_schemas.d.ts.map +1 -1
  50. package/dist/primitive_schemas.js +2 -1
  51. package/dist/schema_meta.d.ts +80 -0
  52. package/dist/schema_meta.d.ts.map +1 -1
  53. package/dist/schema_meta.js +71 -1
  54. package/dist/testing/CLAUDE.md +853 -146
  55. package/dist/testing/admin_integration.d.ts.map +1 -1
  56. package/dist/testing/admin_integration.js +73 -5
  57. package/dist/testing/adversarial_input.d.ts +0 -47
  58. package/dist/testing/adversarial_input.d.ts.map +1 -1
  59. package/dist/testing/adversarial_input.js +4 -340
  60. package/dist/testing/adversarial_input_cases.d.ts +124 -0
  61. package/dist/testing/adversarial_input_cases.d.ts.map +1 -0
  62. package/dist/testing/adversarial_input_cases.js +393 -0
  63. package/dist/testing/audit_completeness.d.ts.map +1 -1
  64. package/dist/testing/audit_completeness.js +24 -20
  65. package/dist/testing/audit_drift_guard.d.ts +30 -3
  66. package/dist/testing/audit_drift_guard.d.ts.map +1 -1
  67. package/dist/testing/audit_drift_guard.js +55 -3
  68. package/dist/testing/cross_backend/account_lifecycle.d.ts.map +1 -1
  69. package/dist/testing/cross_backend/account_lifecycle.js +29 -12
  70. package/dist/testing/cross_backend/actor_lookup.d.ts.map +1 -1
  71. package/dist/testing/cross_backend/actor_lookup.js +7 -25
  72. package/dist/testing/cross_backend/app_settings.d.ts.map +1 -1
  73. package/dist/testing/cross_backend/app_settings.js +4 -6
  74. package/dist/testing/cross_backend/audit_cross_helpers.d.ts +57 -0
  75. package/dist/testing/cross_backend/audit_cross_helpers.d.ts.map +1 -0
  76. package/dist/testing/cross_backend/audit_cross_helpers.js +89 -0
  77. package/dist/testing/cross_backend/backend_config.d.ts +2 -1
  78. package/dist/testing/cross_backend/backend_config.d.ts.map +1 -1
  79. package/dist/testing/cross_backend/body_size.d.ts +6 -0
  80. package/dist/testing/cross_backend/body_size.d.ts.map +1 -1
  81. package/dist/testing/cross_backend/body_size.js +26 -44
  82. package/dist/testing/cross_backend/body_size_smuggling.d.ts +5 -0
  83. package/dist/testing/cross_backend/body_size_smuggling.d.ts.map +1 -1
  84. package/dist/testing/cross_backend/body_size_smuggling.js +7 -14
  85. package/dist/testing/cross_backend/build_test_backend_paths.d.ts +3 -1
  86. package/dist/testing/cross_backend/build_test_backend_paths.d.ts.map +1 -1
  87. package/dist/testing/cross_backend/capabilities.d.ts +78 -59
  88. package/dist/testing/cross_backend/capabilities.d.ts.map +1 -1
  89. package/dist/testing/cross_backend/capabilities.js +25 -24
  90. package/dist/testing/cross_backend/cargo_binary.d.ts +70 -0
  91. package/dist/testing/cross_backend/cargo_binary.d.ts.map +1 -0
  92. package/dist/testing/cross_backend/cargo_binary.js +148 -0
  93. package/dist/testing/cross_backend/cell_crud.d.ts.map +1 -1
  94. package/dist/testing/cross_backend/cell_crud.js +174 -3
  95. package/dist/testing/cross_backend/cell_gated_create.d.ts +0 -60
  96. package/dist/testing/cross_backend/cell_gated_create.d.ts.map +1 -1
  97. package/dist/testing/cross_backend/cell_gated_create.js +9 -487
  98. package/dist/testing/cross_backend/cell_grant_role.d.ts +14 -2
  99. package/dist/testing/cross_backend/cell_grant_role.d.ts.map +1 -1
  100. package/dist/testing/cross_backend/cell_grant_role.js +22 -12
  101. package/dist/testing/cross_backend/cell_moderate.d.ts +66 -0
  102. package/dist/testing/cross_backend/cell_moderate.d.ts.map +1 -0
  103. package/dist/testing/cross_backend/cell_moderate.js +511 -0
  104. package/dist/testing/cross_backend/cell_ref_admission.d.ts.map +1 -1
  105. package/dist/testing/cross_backend/cell_ref_admission.js +1 -1
  106. package/dist/testing/cross_backend/cell_relations.d.ts.map +1 -1
  107. package/dist/testing/cross_backend/cell_relations.js +40 -19
  108. package/dist/testing/cross_backend/conformance_case.d.ts +43 -4
  109. package/dist/testing/cross_backend/conformance_case.d.ts.map +1 -1
  110. package/dist/testing/cross_backend/conformance_case.js +29 -1
  111. package/dist/testing/cross_backend/conformance_rpc_auth.d.ts +93 -0
  112. package/dist/testing/cross_backend/conformance_rpc_auth.d.ts.map +1 -0
  113. package/dist/testing/cross_backend/conformance_rpc_auth.js +125 -0
  114. package/dist/testing/cross_backend/conformance_table.d.ts +144 -4
  115. package/dist/testing/cross_backend/conformance_table.d.ts.map +1 -1
  116. package/dist/testing/cross_backend/conformance_table.js +297 -65
  117. package/dist/testing/cross_backend/cookie_attributes.d.ts.map +1 -1
  118. package/dist/testing/cross_backend/cookie_attributes.js +3 -2
  119. package/dist/testing/cross_backend/create_cross_backend_global_setup.d.ts +38 -5
  120. package/dist/testing/cross_backend/create_cross_backend_global_setup.d.ts.map +1 -1
  121. package/dist/testing/cross_backend/create_cross_backend_global_setup.js +24 -3
  122. package/dist/testing/cross_backend/create_dual_spawn_global_setup.d.ts +5 -5
  123. package/dist/testing/cross_backend/create_dual_spawn_global_setup.d.ts.map +1 -1
  124. package/dist/testing/cross_backend/credential_deadline.d.ts +10 -6
  125. package/dist/testing/cross_backend/credential_deadline.d.ts.map +1 -1
  126. package/dist/testing/cross_backend/credential_deadline.js +32 -31
  127. package/dist/testing/cross_backend/credential_header_robustness.d.ts.map +1 -1
  128. package/dist/testing/cross_backend/credential_header_robustness.js +4 -6
  129. package/dist/testing/cross_backend/{cell_cross_helpers.d.ts → cross_rpc.d.ts} +14 -2
  130. package/dist/testing/cross_backend/cross_rpc.d.ts.map +1 -0
  131. package/dist/testing/cross_backend/{cell_cross_helpers.js → cross_rpc.js} +31 -7
  132. package/dist/testing/cross_backend/default_backend_configs.d.ts +58 -61
  133. package/dist/testing/cross_backend/default_backend_configs.d.ts.map +1 -1
  134. package/dist/testing/cross_backend/default_backend_configs.js +97 -91
  135. package/dist/testing/cross_backend/default_spine_surface.d.ts.map +1 -1
  136. package/dist/testing/cross_backend/default_spine_surface.js +2 -2
  137. package/dist/testing/cross_backend/differential.d.ts +126 -0
  138. package/dist/testing/cross_backend/differential.d.ts.map +1 -0
  139. package/dist/testing/cross_backend/differential.js +201 -0
  140. package/dist/testing/cross_backend/differential_normalize.d.ts +150 -0
  141. package/dist/testing/cross_backend/differential_normalize.d.ts.map +1 -0
  142. package/dist/testing/cross_backend/differential_normalize.js +153 -0
  143. package/dist/testing/cross_backend/fact_serving.d.ts.map +1 -1
  144. package/dist/testing/cross_backend/fact_serving.js +27 -17
  145. package/dist/testing/cross_backend/full_spine_mount.d.ts +15 -0
  146. package/dist/testing/cross_backend/full_spine_mount.d.ts.map +1 -1
  147. package/dist/testing/cross_backend/full_spine_mount.js +55 -1
  148. package/dist/testing/cross_backend/identity_parity.d.ts.map +1 -1
  149. package/dist/testing/cross_backend/identity_parity.js +6 -5
  150. package/dist/testing/cross_backend/in_process_setup.d.ts +12 -2
  151. package/dist/testing/cross_backend/in_process_setup.d.ts.map +1 -1
  152. package/dist/testing/cross_backend/in_process_setup.js +10 -7
  153. package/dist/testing/cross_backend/login_security.d.ts.map +1 -1
  154. package/dist/testing/cross_backend/login_security.js +13 -18
  155. package/dist/testing/cross_backend/origin.js +1 -1
  156. package/dist/testing/cross_backend/origin_conformance.js +1 -1
  157. package/dist/testing/cross_backend/origin_scope.d.ts +6 -0
  158. package/dist/testing/cross_backend/origin_scope.d.ts.map +1 -1
  159. package/dist/testing/cross_backend/origin_scope.js +13 -12
  160. package/dist/testing/cross_backend/peer_ping_ws.d.ts +2 -5
  161. package/dist/testing/cross_backend/peer_ping_ws.d.ts.map +1 -1
  162. package/dist/testing/cross_backend/peer_ping_ws.js +14 -24
  163. package/dist/testing/cross_backend/postgres_database.d.ts +85 -0
  164. package/dist/testing/cross_backend/postgres_database.d.ts.map +1 -0
  165. package/dist/testing/cross_backend/postgres_database.js +140 -0
  166. package/dist/testing/cross_backend/provided_context.d.ts +28 -0
  167. package/dist/testing/cross_backend/provided_context.d.ts.map +1 -0
  168. package/dist/testing/cross_backend/provided_context.js +35 -0
  169. package/dist/testing/cross_backend/query_shape.d.ts.map +1 -1
  170. package/dist/testing/cross_backend/query_shape.js +10 -12
  171. package/dist/testing/cross_backend/ready.js +2 -2
  172. package/dist/testing/cross_backend/revocation_drivers.d.ts +4 -3
  173. package/dist/testing/cross_backend/revocation_drivers.d.ts.map +1 -1
  174. package/dist/testing/cross_backend/revocation_drivers.js +1 -1
  175. package/dist/testing/cross_backend/role_grant_cross_helpers.d.ts +3 -2
  176. package/dist/testing/cross_backend/role_grant_cross_helpers.d.ts.map +1 -1
  177. package/dist/testing/cross_backend/role_grant_offer_lifecycle.d.ts +13 -0
  178. package/dist/testing/cross_backend/role_grant_offer_lifecycle.d.ts.map +1 -0
  179. package/dist/testing/cross_backend/role_grant_offer_lifecycle.js +203 -0
  180. package/dist/testing/cross_backend/role_grant_offer_notification_ws.d.ts +2 -5
  181. package/dist/testing/cross_backend/role_grant_offer_notification_ws.d.ts.map +1 -1
  182. package/dist/testing/cross_backend/role_grant_offer_notification_ws.js +203 -111
  183. package/dist/testing/cross_backend/role_grant_participation.d.ts +13 -0
  184. package/dist/testing/cross_backend/role_grant_participation.d.ts.map +1 -1
  185. package/dist/testing/cross_backend/role_grant_participation.js +32 -21
  186. package/dist/testing/cross_backend/role_grant_role_grammar.d.ts.map +1 -1
  187. package/dist/testing/cross_backend/role_grant_role_grammar.js +6 -9
  188. package/dist/testing/cross_backend/rpc_adversarial.d.ts +47 -0
  189. package/dist/testing/cross_backend/rpc_adversarial.d.ts.map +1 -0
  190. package/dist/testing/cross_backend/rpc_adversarial.js +302 -0
  191. package/dist/testing/cross_backend/rpc_success_fixtures.d.ts +24 -0
  192. package/dist/testing/cross_backend/rpc_success_fixtures.d.ts.map +1 -0
  193. package/dist/testing/cross_backend/rpc_success_fixtures.js +124 -0
  194. package/dist/testing/cross_backend/rust_spine_consumer_surface.d.ts +101 -0
  195. package/dist/testing/cross_backend/rust_spine_consumer_surface.d.ts.map +1 -0
  196. package/dist/testing/cross_backend/rust_spine_consumer_surface.js +113 -0
  197. package/dist/testing/cross_backend/rust_spine_stub_backend_config.d.ts +10 -0
  198. package/dist/testing/cross_backend/rust_spine_stub_backend_config.d.ts.map +1 -1
  199. package/dist/testing/cross_backend/rust_spine_stub_backend_config.js +33 -21
  200. package/dist/testing/cross_backend/session_cap.d.ts +9 -8
  201. package/dist/testing/cross_backend/session_cap.d.ts.map +1 -1
  202. package/dist/testing/cross_backend/session_cap.js +9 -4
  203. package/dist/testing/cross_backend/session_cookie_codec.js +1 -1
  204. package/dist/testing/cross_backend/setup.d.ts +58 -56
  205. package/dist/testing/cross_backend/setup.d.ts.map +1 -1
  206. package/dist/testing/cross_backend/setup.js +29 -29
  207. package/dist/testing/cross_backend/simple_request.d.ts.map +1 -1
  208. package/dist/testing/cross_backend/simple_request.js +4 -4
  209. package/dist/testing/cross_backend/spawn_backend.d.ts +59 -10
  210. package/dist/testing/cross_backend/spawn_backend.d.ts.map +1 -1
  211. package/dist/testing/cross_backend/spawn_backend.js +219 -60
  212. package/dist/testing/cross_backend/spine_suites.d.ts +311 -0
  213. package/dist/testing/cross_backend/spine_suites.d.ts.map +1 -0
  214. package/dist/testing/cross_backend/spine_suites.js +897 -0
  215. package/dist/testing/cross_backend/spine_surface_constants.d.ts +44 -0
  216. package/dist/testing/cross_backend/spine_surface_constants.d.ts.map +1 -1
  217. package/dist/testing/cross_backend/spine_surface_constants.js +53 -0
  218. package/dist/testing/cross_backend/sse_round_trip.d.ts.map +1 -1
  219. package/dist/testing/cross_backend/sse_round_trip.js +3 -4
  220. package/dist/testing/cross_backend/standard.d.ts +18 -1
  221. package/dist/testing/cross_backend/standard.d.ts.map +1 -1
  222. package/dist/testing/cross_backend/standard.js +2 -0
  223. package/dist/testing/cross_backend/test_cell_gated_create_authorize.d.ts +24 -0
  224. package/dist/testing/cross_backend/test_cell_gated_create_authorize.d.ts.map +1 -1
  225. package/dist/testing/cross_backend/test_cell_gated_create_authorize.js +15 -0
  226. package/dist/testing/cross_backend/testing_backdoor.d.ts +29 -12
  227. package/dist/testing/cross_backend/testing_backdoor.d.ts.map +1 -1
  228. package/dist/testing/cross_backend/testing_backdoor.js +143 -51
  229. package/dist/testing/cross_backend/testing_reset_actions.d.ts +30 -14
  230. package/dist/testing/cross_backend/testing_reset_actions.d.ts.map +1 -1
  231. package/dist/testing/cross_backend/testing_reset_actions.js +58 -37
  232. package/dist/testing/cross_backend/testing_server_bun.js +1 -1
  233. package/dist/testing/cross_backend/token_lifetime.js +1 -1
  234. package/dist/testing/cross_backend/token_scope_surface.d.ts.map +1 -1
  235. package/dist/testing/cross_backend/token_scope_surface.js +9 -13
  236. package/dist/testing/cross_backend/transport_composition.d.ts +26 -2
  237. package/dist/testing/cross_backend/transport_composition.d.ts.map +1 -1
  238. package/dist/testing/cross_backend/transport_composition.js +81 -51
  239. package/dist/testing/cross_backend/ts_spine_backend_config.d.ts +8 -0
  240. package/dist/testing/cross_backend/ts_spine_backend_config.d.ts.map +1 -1
  241. package/dist/testing/cross_backend/ts_spine_backend_config.js +23 -13
  242. package/dist/testing/cross_backend/ws_action_rate_limit.d.ts +2 -5
  243. package/dist/testing/cross_backend/ws_action_rate_limit.d.ts.map +1 -1
  244. package/dist/testing/cross_backend/ws_action_rate_limit.js +8 -14
  245. package/dist/testing/cross_backend/ws_connection_cap.d.ts +4 -9
  246. package/dist/testing/cross_backend/ws_connection_cap.d.ts.map +1 -1
  247. package/dist/testing/cross_backend/ws_connection_cap.js +11 -12
  248. package/dist/testing/cross_backend/ws_endpoint.d.ts +52 -0
  249. package/dist/testing/cross_backend/ws_endpoint.d.ts.map +1 -0
  250. package/dist/testing/cross_backend/ws_endpoint.js +54 -0
  251. package/dist/testing/cross_backend/ws_inbound_dispatch.d.ts +2 -5
  252. package/dist/testing/cross_backend/ws_inbound_dispatch.d.ts.map +1 -1
  253. package/dist/testing/cross_backend/ws_inbound_dispatch.js +9 -15
  254. package/dist/testing/cross_backend/ws_outbound_overflow.d.ts +2 -7
  255. package/dist/testing/cross_backend/ws_outbound_overflow.d.ts.map +1 -1
  256. package/dist/testing/cross_backend/ws_outbound_overflow.js +5 -9
  257. package/dist/testing/cross_backend/ws_role_gated.d.ts +4 -5
  258. package/dist/testing/cross_backend/ws_role_gated.d.ts.map +1 -1
  259. package/dist/testing/cross_backend/ws_role_gated.js +12 -21
  260. package/dist/testing/cross_backend/ws_round_trip.d.ts +12 -9
  261. package/dist/testing/cross_backend/ws_round_trip.d.ts.map +1 -1
  262. package/dist/testing/cross_backend/ws_round_trip.js +29 -34
  263. package/dist/testing/db_entities.d.ts +16 -3
  264. package/dist/testing/db_entities.d.ts.map +1 -1
  265. package/dist/testing/db_entities.js +28 -5
  266. package/dist/testing/integration_helpers.d.ts +61 -2
  267. package/dist/testing/integration_helpers.d.ts.map +1 -1
  268. package/dist/testing/integration_helpers.js +75 -18
  269. package/dist/testing/round_trip.d.ts +17 -0
  270. package/dist/testing/round_trip.d.ts.map +1 -1
  271. package/dist/testing/round_trip.js +67 -24
  272. package/dist/testing/rpc_attack_surface.d.ts +10 -0
  273. package/dist/testing/rpc_attack_surface.d.ts.map +1 -1
  274. package/dist/testing/rpc_attack_surface.js +27 -140
  275. package/dist/testing/rpc_envelope_cases.d.ts +114 -0
  276. package/dist/testing/rpc_envelope_cases.d.ts.map +1 -0
  277. package/dist/testing/rpc_envelope_cases.js +243 -0
  278. package/dist/testing/rpc_helpers.d.ts +31 -0
  279. package/dist/testing/rpc_helpers.d.ts.map +1 -1
  280. package/dist/testing/rpc_helpers.js +35 -14
  281. package/dist/testing/rpc_round_trip.d.ts +62 -6
  282. package/dist/testing/rpc_round_trip.d.ts.map +1 -1
  283. package/dist/testing/rpc_round_trip.js +151 -39
  284. package/dist/testing/schema_generators.d.ts +99 -2
  285. package/dist/testing/schema_generators.d.ts.map +1 -1
  286. package/dist/testing/schema_generators.js +261 -73
  287. package/dist/testing/standard.d.ts +26 -0
  288. package/dist/testing/standard.d.ts.map +1 -1
  289. package/dist/testing/standard.js +4 -1
  290. package/dist/testing/stubs.d.ts +4 -3
  291. package/dist/testing/stubs.d.ts.map +1 -1
  292. package/dist/testing/stubs.js +6 -4
  293. package/dist/testing/transports/raw_http.d.ts +21 -0
  294. package/dist/testing/transports/raw_http.d.ts.map +1 -1
  295. package/dist/testing/transports/raw_http.js +30 -0
  296. package/dist/zod.d.ts +9 -0
  297. package/dist/zod.d.ts.map +1 -1
  298. package/dist/zod.js +20 -0
  299. package/package.json +6 -4
  300. package/dist/testing/cross_backend/actor_search.d.ts +0 -6
  301. package/dist/testing/cross_backend/actor_search.d.ts.map +0 -1
  302. package/dist/testing/cross_backend/actor_search.js +0 -90
  303. package/dist/testing/cross_backend/cell_cross_helpers.d.ts.map +0 -1
@@ -13,8 +13,43 @@ export declare const TESTING_ACTION_AUTH: {
13
13
  readonly actor: "none";
14
14
  readonly credential_types: readonly ["daemon_token"];
15
15
  };
16
+ /**
17
+ * Every `_testing_*` backdoor the shipped cross suites know: the daemon-token
18
+ * actions a test binary may mount for the harness to drive. The one list a
19
+ * backend's `capabilities.testing_backdoors` declares from, the
20
+ * testing-backdoor suite probes, and `describe_spine_cross_suites` gates suites
21
+ * on. A consumer's own seams stay off it — the testing-backdoor suite takes
22
+ * those as `extra_methods`.
23
+ *
24
+ * `spine_surface_constants.testing_backdoors.test.ts` holds it to the `_testing_*` methods
25
+ * fuz_app's spine binary mounts, so an action added there fails until it is
26
+ * listed here.
27
+ */
28
+ export declare const TESTING_BACKDOOR_METHODS: readonly ["_testing_reset", "_testing_drain_effects", "_testing_mint_session", "_testing_put_fact", "_testing_flood_notifications", "_testing_schema_snapshot", "_testing_migration_tracker", "_testing_action_manifest", "_testing_origin_check", "_testing_shorten_credential_expiry"];
29
+ /** A `_testing_*` backdoor the shipped cross suites know — see `TESTING_BACKDOOR_METHODS`. */
30
+ export type TestingBackdoorMethod = (typeof TESTING_BACKDOOR_METHODS)[number];
16
31
  /** RPC endpoint mount path — matches the binary's `/api/rpc`. */
17
32
  export declare const SPINE_RPC_PATH = "/api/rpc";
33
+ /** Ungated WebSocket endpoint mount path — matches the binaries' `/api/ws`. */
34
+ export declare const SPINE_WS_PATH = "/api/ws";
35
+ /**
36
+ * Mount prefix of the account REST routes (login, logout, password, status,
37
+ * signup, bootstrap) on both spine binaries. The `SPINE_ACCOUNT_*_PATH`
38
+ * constants below are the routes under it the suites drive.
39
+ */
40
+ export declare const SPINE_ACCOUNT_PATH_PREFIX = "/api/account";
41
+ /** REST login route. */
42
+ export declare const SPINE_ACCOUNT_LOGIN_PATH = "/api/account/login";
43
+ /** REST logout route. */
44
+ export declare const SPINE_ACCOUNT_LOGOUT_PATH = "/api/account/logout";
45
+ /** REST password-change route. */
46
+ export declare const SPINE_ACCOUNT_PASSWORD_PATH = "/api/account/password";
47
+ /** REST account-status route. */
48
+ export declare const SPINE_ACCOUNT_STATUS_PATH = "/api/account/status";
49
+ /** REST signup route. */
50
+ export declare const SPINE_ACCOUNT_SIGNUP_PATH = "/api/account/signup";
51
+ /** REST bootstrap route — the default `BackendConfig.bootstrap_path`. */
52
+ export declare const SPINE_ACCOUNT_BOOTSTRAP_PATH = "/api/account/bootstrap";
18
53
  /**
19
54
  * Audit-log SSE stream path — `/api/admin` prefix + the
20
55
  * `create_audit_log_route_specs` `/audit/stream` route. Matches the default
@@ -23,6 +58,15 @@ export declare const SPINE_RPC_PATH = "/api/rpc";
23
58
  * surface stub leaves `ctx.audit_sse` null so the snapshot stays SSE-free.
24
59
  */
25
60
  export declare const SPINE_SSE_PATH = "/api/admin/audit/stream";
61
+ /**
62
+ * The request-body cap both spines ship by default, 1 MiB
63
+ * (`DEFAULT_MAX_BODY_SIZE` in TS, `DEFAULT_BODY_LIMIT_BYTES` in `fuz_http`).
64
+ * Kept here as the cross-impl contract value rather than imported from either
65
+ * impl — the boundary the body-size suites pin is the shared default, and a
66
+ * change to either is a deliberate cross-impl decision that would revisit them
67
+ * regardless.
68
+ */
69
+ export declare const SPINE_BODY_LIMIT_DEFAULT_BYTES: number;
26
70
  /**
27
71
  * App role the role-shaped-`cell_grant` cross suite exercises. Registered
28
72
  * with no grant path (`grant_paths: []`) so it stays a valid registry member
@@ -1 +1 @@
1
- {"version":3,"file":"spine_surface_constants.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/spine_surface_constants.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AA4B9B;;;;;;;;GAQG;AACH,eAAO,MAAM,mBAAmB;;;;CAIF,CAAC;AAE/B,iEAAiE;AACjE,eAAO,MAAM,cAAc,aAAa,CAAC;AAEzC;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,4BAA4B,CAAC;AAExD;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,gBAAgB,CAAC;AAEpD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,sBAAsB,gBAAgB,CAAC;AAEpD;;;;;;;;;GASG;AACH,eAAO,MAAM,wBAAwB,kBAAkB,CAAC;AAExD;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB,EAAE,aAAa,CAAC,MAAM,CAG1D,CAAC;AAEH;;;;;;;;;;GAUG;AACH,eAAO,MAAM,yBAAyB,EAAE,GAAwD,CAAC;AAEjG;;;;;;;GAOG;AACH,eAAO,MAAM,4BAA4B,iCAAiC,CAAC;AAE3E;;;;;;;;GAQG;AACH,eAAO,MAAM,6BAA6B,kCAAkC,CAAC;AAE7E;;;;;;GAMG;AACH,eAAO,MAAM,kCAAkC,uCAAuC,CAAC;AAEvF;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,6BAA6B,CAAC"}
1
+ {"version":3,"file":"spine_surface_constants.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/spine_surface_constants.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AA4B9B;;;;;;;;GAQG;AACH,eAAO,MAAM,mBAAmB;;;;CAIF,CAAC;AAE/B;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,wBAAwB,0RAW3B,CAAC;AAEX,8FAA8F;AAC9F,MAAM,MAAM,qBAAqB,GAAG,CAAC,OAAO,wBAAwB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE9E,iEAAiE;AACjE,eAAO,MAAM,cAAc,aAAa,CAAC;AAEzC,+EAA+E;AAC/E,eAAO,MAAM,aAAa,YAAY,CAAC;AAEvC;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,iBAAiB,CAAC;AAExD,wBAAwB;AACxB,eAAO,MAAM,wBAAwB,uBAAuB,CAAC;AAE7D,yBAAyB;AACzB,eAAO,MAAM,yBAAyB,wBAAwB,CAAC;AAE/D,kCAAkC;AAClC,eAAO,MAAM,2BAA2B,0BAA0B,CAAC;AAEnE,iCAAiC;AACjC,eAAO,MAAM,yBAAyB,wBAAwB,CAAC;AAE/D,yBAAyB;AACzB,eAAO,MAAM,yBAAyB,wBAAwB,CAAC;AAE/D,yEAAyE;AACzE,eAAO,MAAM,4BAA4B,2BAA2B,CAAC;AAErE;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,4BAA4B,CAAC;AAExD;;;;;;;GAOG;AACH,eAAO,MAAM,8BAA8B,QAAc,CAAC;AAE1D;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,gBAAgB,CAAC;AAEpD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,sBAAsB,gBAAgB,CAAC;AAEpD;;;;;;;;;GASG;AACH,eAAO,MAAM,wBAAwB,kBAAkB,CAAC;AAExD;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB,EAAE,aAAa,CAAC,MAAM,CAG1D,CAAC;AAEH;;;;;;;;;;GAUG;AACH,eAAO,MAAM,yBAAyB,EAAE,GAAwD,CAAC;AAEjG;;;;;;;GAOG;AACH,eAAO,MAAM,4BAA4B,iCAAiC,CAAC;AAE3E;;;;;;;;GAQG;AACH,eAAO,MAAM,6BAA6B,kCAAkC,CAAC;AAE7E;;;;;;GAMG;AACH,eAAO,MAAM,kCAAkC,uCAAuC,CAAC;AAEvF;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,6BAA6B,CAAC"}
@@ -13,8 +13,52 @@ export const TESTING_ACTION_AUTH = {
13
13
  actor: 'none',
14
14
  credential_types: ['daemon_token']
15
15
  };
16
+ /**
17
+ * Every `_testing_*` backdoor the shipped cross suites know: the daemon-token
18
+ * actions a test binary may mount for the harness to drive. The one list a
19
+ * backend's `capabilities.testing_backdoors` declares from, the
20
+ * testing-backdoor suite probes, and `describe_spine_cross_suites` gates suites
21
+ * on. A consumer's own seams stay off it — the testing-backdoor suite takes
22
+ * those as `extra_methods`.
23
+ *
24
+ * `spine_surface_constants.testing_backdoors.test.ts` holds it to the `_testing_*` methods
25
+ * fuz_app's spine binary mounts, so an action added there fails until it is
26
+ * listed here.
27
+ */
28
+ export const TESTING_BACKDOOR_METHODS = [
29
+ '_testing_reset',
30
+ '_testing_drain_effects',
31
+ '_testing_mint_session',
32
+ '_testing_put_fact',
33
+ '_testing_flood_notifications',
34
+ '_testing_schema_snapshot',
35
+ '_testing_migration_tracker',
36
+ '_testing_action_manifest',
37
+ '_testing_origin_check',
38
+ '_testing_shorten_credential_expiry'
39
+ ];
16
40
  /** RPC endpoint mount path — matches the binary's `/api/rpc`. */
17
41
  export const SPINE_RPC_PATH = '/api/rpc';
42
+ /** Ungated WebSocket endpoint mount path — matches the binaries' `/api/ws`. */
43
+ export const SPINE_WS_PATH = '/api/ws';
44
+ /**
45
+ * Mount prefix of the account REST routes (login, logout, password, status,
46
+ * signup, bootstrap) on both spine binaries. The `SPINE_ACCOUNT_*_PATH`
47
+ * constants below are the routes under it the suites drive.
48
+ */
49
+ export const SPINE_ACCOUNT_PATH_PREFIX = '/api/account';
50
+ /** REST login route. */
51
+ export const SPINE_ACCOUNT_LOGIN_PATH = '/api/account/login';
52
+ /** REST logout route. */
53
+ export const SPINE_ACCOUNT_LOGOUT_PATH = '/api/account/logout';
54
+ /** REST password-change route. */
55
+ export const SPINE_ACCOUNT_PASSWORD_PATH = '/api/account/password';
56
+ /** REST account-status route. */
57
+ export const SPINE_ACCOUNT_STATUS_PATH = '/api/account/status';
58
+ /** REST signup route. */
59
+ export const SPINE_ACCOUNT_SIGNUP_PATH = '/api/account/signup';
60
+ /** REST bootstrap route — the default `BackendConfig.bootstrap_path`. */
61
+ export const SPINE_ACCOUNT_BOOTSTRAP_PATH = '/api/account/bootstrap';
18
62
  /**
19
63
  * Audit-log SSE stream path — `/api/admin` prefix + the
20
64
  * `create_audit_log_route_specs` `/audit/stream` route. Matches the default
@@ -23,6 +67,15 @@ export const SPINE_RPC_PATH = '/api/rpc';
23
67
  * surface stub leaves `ctx.audit_sse` null so the snapshot stays SSE-free.
24
68
  */
25
69
  export const SPINE_SSE_PATH = '/api/admin/audit/stream';
70
+ /**
71
+ * The request-body cap both spines ship by default, 1 MiB
72
+ * (`DEFAULT_MAX_BODY_SIZE` in TS, `DEFAULT_BODY_LIMIT_BYTES` in `fuz_http`).
73
+ * Kept here as the cross-impl contract value rather than imported from either
74
+ * impl — the boundary the body-size suites pin is the shared default, and a
75
+ * change to either is a deliberate cross-impl decision that would revisit them
76
+ * regardless.
77
+ */
78
+ export const SPINE_BODY_LIMIT_DEFAULT_BYTES = 1024 * 1024;
26
79
  /**
27
80
  * App role the role-shaped-`cell_grant` cross suite exercises. Registered
28
81
  * with no grant path (`grant_paths: []`) so it stays a valid registry member
@@ -1 +1 @@
1
- {"version":3,"file":"sse_round_trip.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/sse_round_trip.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAkF9B,OAAO,EAAE,KAAK,mBAAmB,EAAW,MAAM,mBAAmB,CAAC;AAEtE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAK5C,4DAA4D;AAC5D,MAAM,WAAW,0BAA0B;IAC1C;;;;;;OAMG;IACH,QAAQ,CAAC,UAAU,EAAE,SAAS,CAAC;IAC/B,wEAAwE;IACxE,QAAQ,CAAC,YAAY,EAAE,mBAAmB,CAAC;IAC3C,2EAA2E;IAC3E,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,6EAA6E;IAC7E,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;;;OAMG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,6DAA6D;IAC7D,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,wFAAwF;IACxF,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,4FAA4F;IAC5F,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CAChC;AA0BD;;;;;;GAMG;AACH,eAAO,MAAM,gCAAgC,GAAI,SAAS,0BAA0B,KAAG,IAyStF,CAAC"}
1
+ {"version":3,"file":"sse_round_trip.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/sse_round_trip.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAkF9B,OAAO,EAAE,KAAK,mBAAmB,EAAW,MAAM,mBAAmB,CAAC;AAEtE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAO5C,4DAA4D;AAC5D,MAAM,WAAW,0BAA0B;IAC1C;;;;;;OAMG;IACH,QAAQ,CAAC,UAAU,EAAE,SAAS,CAAC;IAC/B,wEAAwE;IACxE,QAAQ,CAAC,YAAY,EAAE,mBAAmB,CAAC;IAC3C,2EAA2E;IAC3E,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,6EAA6E;IAC7E,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;;;OAMG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,6DAA6D;IAC7D,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,wFAAwF;IACxF,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,4FAA4F;IAC5F,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CAChC;AA0BD;;;;;;GAMG;AACH,eAAO,MAAM,gCAAgC,GAAI,SAAS,0BAA0B,KAAG,IAyStF,CAAC"}
@@ -69,8 +69,7 @@ import { create_rpc_post_init } from '../rpc_helpers.js';
69
69
  import { DEFAULT_TEST_PASSWORD } from '../test_credentials.js';
70
70
  import { test_if } from './capabilities.js';
71
71
  import { create_account_revocations } from './revocation_drivers.js';
72
- /** Default audit-log SSE stream path — the standard fuz_app `/api/admin/audit/stream`. */
73
- const DEFAULT_SSE_PATH = '/api/admin/audit/stream';
72
+ import { SPINE_ACCOUNT_LOGOUT_PATH, SPINE_ACCOUNT_PASSWORD_PATH, SPINE_SSE_PATH } from './spine_surface_constants.js';
74
73
  /**
75
74
  * Assert a decoded SSE frame is a well-formed audit `{method, params}`
76
75
  * payload whose `params` validate against the matching `audit_log_event_specs`
@@ -94,8 +93,8 @@ const assert_audit_data_frame = (frame) => {
94
93
  * per-session cap.
95
94
  */
96
95
  export const describe_cross_process_sse_tests = (options) => {
97
- const { setup_test, capabilities, base_url, rpc_path, origin, logout_path = '/api/account/logout', password_path = '/api/account/password' } = options;
98
- const sse_path = options.sse_path ?? DEFAULT_SSE_PATH;
96
+ const { setup_test, capabilities, base_url, rpc_path, origin, logout_path = SPINE_ACCOUNT_LOGOUT_PATH, password_path = SPINE_ACCOUNT_PASSWORD_PATH } = options;
97
+ const sse_path = options.sse_path ?? SPINE_SSE_PATH;
99
98
  const max_per_scope = options.max_per_scope === undefined ? AUDIT_LOG_SSE_MAX_PER_SCOPE : options.max_per_scope;
100
99
  describe('cross-process sse', () => {
101
100
  test_if(capabilities.sse, 'connects and emits the connected comment', async () => {
@@ -41,6 +41,7 @@ import '../assert_dev_env.js';
41
41
  import type { SessionOptions } from '../../auth/session_cookie.js';
42
42
  import type { RoleSchemaResult } from '../../auth/role_schema.js';
43
43
  import type { AppSurfaceSpec } from '../../http/surface.js';
44
+ import { type RpcSuccessFixtures } from '../rpc_round_trip.js';
44
45
  import type { RpcEndpointsSuiteOption } from '../rpc_helpers.js';
45
46
  import type { BackendCapabilities } from './capabilities.js';
46
47
  import type { SetupTest, TestFixture } from './setup.js';
@@ -112,7 +113,23 @@ export interface StandardCrossProcessTestOptions {
112
113
  * schema on each backend — the success-shape parity check. See
113
114
  * `RpcRoundTripTestOptions.success_fixtures`.
114
115
  */
115
- rpc_success_fixtures?: Map<string, (fixture: TestFixture) => Promise<Record<string, unknown>>>;
116
+ rpc_success_fixtures?: RpcSuccessFixtures;
117
+ /**
118
+ * Forwarded to `describe_rpc_round_trip_tests` as `skip_methods` — the
119
+ * consumer escape hatch for a method the generic round-trip can't drive at
120
+ * all (a handler whose test wiring stubs out the deps it reaches, or reads
121
+ * tables the suite's database doesn't migrate). Each entry hides the
122
+ * method from both the crash check and the envelope check, so name the
123
+ * reason beside it.
124
+ */
125
+ rpc_skip_methods?: Array<string>;
126
+ /**
127
+ * Forwarded to `describe_rpc_round_trip_tests` as `input_overrides`
128
+ * (method name → params) — for a method whose generated params can't
129
+ * reach its handler cleanly. The response is held to the same rules as a
130
+ * generated one.
131
+ */
132
+ rpc_input_overrides?: Map<string, Record<string, unknown>>;
116
133
  /**
117
134
  * Forwarded to `describe_round_trip_validation` as `success_fixtures`
118
135
  * (`'METHOD /path'` → async `{url?, body?}` factory) for referential REST
@@ -1 +1 @@
1
- {"version":3,"file":"standard.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/standard.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAE9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAM5D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AACjE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzD;;;;;;GAMG;AACH,MAAM,WAAW,+BAA+B;IAC/C,2CAA2C;IAC3C,UAAU,EAAE,SAAS,CAAC;IACtB;;;OAGG;IACH,cAAc,EAAE,cAAc,CAAC;IAC/B;;;;OAIG;IACH,YAAY,EAAE,mBAAmB,CAAC;IAClC,uFAAuF;IACvF,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC;;;;;OAKG;IACH,aAAa,EAAE,uBAAuB,CAAC;IACvC;;;OAGG;IACH,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;;OAMG;IACH,sBAAsB,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACvC;;;;OAIG;IACH,yBAAyB,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC1C;;;;;;;OAOG;IACH,oBAAoB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IAC/F;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,GAAG,CAC1B,MAAM,EACN,CAAC,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC,CACnF,CAAC;CACF;AAED;;;;GAIG;AACH,eAAO,MAAM,qCAAqC,GACjD,SAAS,+BAA+B,KACtC,IAqCF,CAAC"}
1
+ {"version":3,"file":"standard.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/standard.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAE9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAI5D,OAAO,EAAiC,KAAK,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE9F,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AACjE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzD;;;;;;GAMG;AACH,MAAM,WAAW,+BAA+B;IAC/C,2CAA2C;IAC3C,UAAU,EAAE,SAAS,CAAC;IACtB;;;OAGG;IACH,cAAc,EAAE,cAAc,CAAC;IAC/B;;;;OAIG;IACH,YAAY,EAAE,mBAAmB,CAAC;IAClC,uFAAuF;IACvF,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC;;;;;OAKG;IACH,aAAa,EAAE,uBAAuB,CAAC;IACvC;;;OAGG;IACH,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;;OAMG;IACH,sBAAsB,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACvC;;;;OAIG;IACH,yBAAyB,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC1C;;;;;;;OAOG;IACH,oBAAoB,CAAC,EAAE,kBAAkB,CAAC;IAC1C;;;;;;;OAOG;IACH,gBAAgB,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACjC;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC3D;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,GAAG,CAC1B,MAAM,EACN,CAAC,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC,CACnF,CAAC;CACF;AAED;;;;GAIG;AACH,eAAO,MAAM,qCAAqC,GACjD,SAAS,+BAA+B,KACtC,IAuCF,CAAC"}
@@ -29,6 +29,8 @@ export const describe_standard_cross_process_tests = (options) => {
29
29
  surface_source: options.surface_source,
30
30
  session_options: options.session_options,
31
31
  rpc_endpoints: options.rpc_endpoints,
32
+ skip_methods: options.rpc_skip_methods,
33
+ input_overrides: options.rpc_input_overrides,
32
34
  success_fixtures: options.rpc_success_fixtures
33
35
  });
34
36
  describe_data_exposure_tests({
@@ -8,6 +8,30 @@ export declare const SPACE_CELL_KIND = "space";
8
8
  * `"participant"` literal.
9
9
  */
10
10
  export declare const PARTICIPATION_ROLE = "participant";
11
+ /**
12
+ * A space `data.policy` mirroring the test ladder: gated `post` (moderated) +
13
+ * `react` (live) + `comment` (live), each on `PARTICIPATION_ROLE`. `comment`
14
+ * exists so a suite can create a comment under a post (`root_id !==
15
+ * parent_id`) and prove the policy resolves from the governing root (the
16
+ * space), not the immediate parent. Shared by the gated-create and moderate
17
+ * cross suites.
18
+ */
19
+ export declare const TEST_SPACE_POLICY: {
20
+ readonly policy: {
21
+ readonly post: {
22
+ readonly min_role: "participant";
23
+ readonly moderation_required: true;
24
+ };
25
+ readonly react: {
26
+ readonly min_role: "participant";
27
+ readonly moderation_required: false;
28
+ };
29
+ readonly comment: {
30
+ readonly min_role: "participant";
31
+ readonly moderation_required: false;
32
+ };
33
+ };
34
+ };
11
35
  /** A space's per-kind contribution rule (the shape stamped into `space.data.policy`). */
12
36
  export interface ContributionRule {
13
37
  min_role?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"test_cell_gated_create_authorize.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/test_cell_gated_create_authorize.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AA4B9B,OAAO,KAAK,EACX,mBAAmB,EAGnB,MAAM,4BAA4B,CAAC;AAGpC,8EAA8E;AAC9E,eAAO,MAAM,eAAe,UAAU,CAAC;AAEvC;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,gBAAyB,CAAC;AAEzD,yFAAyF;AACzF,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAYD;;;;GAIG;AACH,eAAO,MAAM,gCAAgC,EAAE,mBAsB9C,CAAC"}
1
+ {"version":3,"file":"test_cell_gated_create_authorize.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/test_cell_gated_create_authorize.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AA4B9B,OAAO,KAAK,EACX,mBAAmB,EAGnB,MAAM,4BAA4B,CAAC;AAGpC,8EAA8E;AAC9E,eAAO,MAAM,eAAe,UAAU,CAAC;AAEvC;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,gBAAyB,CAAC;AAEzD;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;CAMpB,CAAC;AAEX,yFAAyF;AACzF,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAYD;;;;GAIG;AACH,eAAO,MAAM,gCAAgC,EAAE,mBAsB9C,CAAC"}
@@ -33,6 +33,21 @@ export const SPACE_CELL_KIND = 'space';
33
33
  * `"participant"` literal.
34
34
  */
35
35
  export const PARTICIPATION_ROLE = SPINE_PARTICIPANT_ROLE;
36
+ /**
37
+ * A space `data.policy` mirroring the test ladder: gated `post` (moderated) +
38
+ * `react` (live) + `comment` (live), each on `PARTICIPATION_ROLE`. `comment`
39
+ * exists so a suite can create a comment under a post (`root_id !==
40
+ * parent_id`) and prove the policy resolves from the governing root (the
41
+ * space), not the immediate parent. Shared by the gated-create and moderate
42
+ * cross suites.
43
+ */
44
+ export const TEST_SPACE_POLICY = {
45
+ policy: {
46
+ post: { min_role: PARTICIPATION_ROLE, moderation_required: true },
47
+ react: { min_role: PARTICIPATION_ROLE, moderation_required: false },
48
+ comment: { min_role: PARTICIPATION_ROLE, moderation_required: false }
49
+ }
50
+ };
36
51
  /** Pull the governing root's `data.policy[kind]` rule, defensively (loose `data`). */
37
52
  const get_contribution_rule = (data, kind) => {
38
53
  if (data === null || typeof data !== 'object')
@@ -1,20 +1,37 @@
1
1
  import '../assert_dev_env.js';
2
- import type { RpcPathCrossSuiteOptions } from './setup.js';
3
- /** Options for the testing-backdoor negative-credential suite. */
4
- export interface TestingBackdoorCrossTestOptions extends RpcPathCrossSuiteOptions {
2
+ import type { RpcPathCapabilityGatedCrossSuiteOptions } from './setup.js';
3
+ import { type WsEndpointTarget } from './ws_endpoint.js';
4
+ /**
5
+ * A backdoor the suite fires: its method and a params payload its input
6
+ * schema accepts, so a refusal lands on the credential gate, not on validation.
7
+ */
8
+ export interface TestingBackdoorProbe {
9
+ readonly method: string;
10
+ readonly params?: unknown;
11
+ }
12
+ /** Options for the testing-backdoor suite. */
13
+ export interface TestingBackdoorCrossTestOptions extends RpcPathCapabilityGatedCrossSuiteOptions {
5
14
  /**
6
15
  * Where the backend's WebSocket endpoint is, for the session-socket cases.
7
- * Pass it when the backend serves the `_testing_*` actions on its WS
16
+ * Pass it when the backend serves its `_testing_*` actions on its WS
8
17
  * endpoint too; omitted, those cases are skipped.
9
18
  */
10
- readonly ws?: {
11
- /** Base URL the backend is reachable at (e.g. `http://localhost:1178`). */
12
- readonly base_url: string;
13
- /** WebSocket endpoint path on the backend (e.g. `/api/ws`). */
14
- readonly ws_path: string;
15
- /** Origin for the upgrade. Defaults to `base_url`. */
16
- readonly origin?: string;
17
- };
19
+ readonly ws?: WsEndpointTarget;
20
+ /**
21
+ * The backend's own daemon-token seams beyond `TESTING_BACKDOOR_METHODS`,
22
+ * each with params its input accepts — fired with the same refused
23
+ * principals as the known backdoors. Each must start with `_testing_` and
24
+ * not be a known backdoor; the call throws otherwise.
25
+ */
26
+ readonly extra_methods?: ReadonlyArray<TestingBackdoorProbe>;
18
27
  }
28
+ /**
29
+ * Register the backdoor suite: the declaration check over every known
30
+ * backdoor, then the refused-principal rows over the mounted ones.
31
+ *
32
+ * @param options - the fixture, the backend's capabilities, and the optional
33
+ * WS target and extra seams
34
+ * @throws Error - on a declaration or extra method `resolve_backdoor_probes` refuses
35
+ */
19
36
  export declare const describe_testing_backdoor_cross_tests: (options: TestingBackdoorCrossTestOptions) => void;
20
37
  //# sourceMappingURL=testing_backdoor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"testing_backdoor.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/testing_backdoor.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AA4E9B,OAAO,KAAK,EAAE,wBAAwB,EAAe,MAAM,YAAY,CAAC;AAyFxE,kEAAkE;AAClE,MAAM,WAAW,+BAAgC,SAAQ,wBAAwB;IAChF;;;;OAIG;IACH,QAAQ,CAAC,EAAE,CAAC,EAAE;QACb,2EAA2E;QAC3E,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B,+DAA+D;QAC/D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,sDAAsD;QACtD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;KACzB,CAAC;CACF;AAED,eAAO,MAAM,qCAAqC,GACjD,SAAS,+BAA+B,KACtC,IAyEF,CAAC"}
1
+ {"version":3,"file":"testing_backdoor.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/testing_backdoor.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AA2F9B,OAAO,KAAK,EAAE,uCAAuC,EAAe,MAAM,YAAY,CAAC;AAMvF,OAAO,EAAmB,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AA0C1E;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC1B;AAkDD,8CAA8C;AAC9C,MAAM,WAAW,+BAAgC,SAAQ,uCAAuC;IAC/F;;;;OAIG;IACH,QAAQ,CAAC,EAAE,CAAC,EAAE,gBAAgB,CAAC;IAC/B;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,aAAa,CAAC,oBAAoB,CAAC,CAAC;CAC7D;AAqDD;;;;;;;GAOG;AACH,eAAO,MAAM,qCAAqC,GACjD,SAAS,+BAA+B,KACtC,IAgHF,CAAC"}
@@ -1,28 +1,43 @@
1
1
  import '../assert_dev_env.js';
2
2
  /**
3
- * Cross-backend negative-credential suite for the `_testing_*` backdoor
4
- * actions.
3
+ * Cross-backend suite for the `_testing_*` backdoor actions: the backend's
4
+ * declaration of which it mounts, and the credential gate on each.
5
5
  *
6
- * `_testing_reset` / `_testing_mint_session` / `_testing_put_fact` /
7
- * `_testing_flood_notifications` / `_testing_schema_snapshot` /
8
- * `_testing_migration_tracker` / `_testing_action_manifest` /
9
- * `_testing_origin_check` / `_testing_shorten_credential_expiry` are
6
+ * `TESTING_BACKDOOR_METHODS` (`_testing_reset`, `_testing_drain_effects`,
7
+ * `_testing_mint_session`, `_testing_put_fact`,
8
+ * `_testing_flood_notifications`, `_testing_schema_snapshot`,
9
+ * `_testing_migration_tracker`, `_testing_action_manifest`,
10
+ * `_testing_origin_check`, `_testing_shorten_credential_expiry`) are
10
11
  * privileged test-binary actions the production
11
12
  * wire never exposes — direct DB writes (full auth wipe, forged session row,
12
- * raw fact insert), a flood of the caller's own connection, introspection
13
- * reads (the live schema, the `schema_version` migration tracker, and the live
14
- * RPC registry — the highest info-leak of the set were the gate to break), a
15
- * probe of the origin allowlist parser, and a rewrite of an account's
16
- * credential expiries. Their only structural fence
13
+ * raw fact insert), the audit barrier, a flood of the caller's own connection,
14
+ * introspection reads (the live schema, the `schema_version` migration
15
+ * tracker, and the live RPC registry — the highest info-leak of the set were
16
+ * the gate to break), a probe of the origin allowlist parser, and a rewrite of
17
+ * an account's credential expiries. Their only structural fence
17
18
  * is the **daemon-token** credential gate on
18
19
  * each spec's `auth` axis. A test binary live-mounts them on its RPC
19
20
  * endpoint (and, on fuz_app's spine binary and the Rust stub, its WS
20
21
  * endpoint) but keeps them off the declared surface — so the spec-derived
21
- * `describe_rpc_attack_surface_tests` never enumerates them, and nothing
22
- * else fires them with a non-daemon credential to prove the gate holds
23
- * end-to-end. This suite does, against each impl's real auth resolution.
22
+ * `describe_rpc_attack_surface_tests` never enumerates them. This suite fires
23
+ * them with non-daemon credentials to prove the gate holds end-to-end, against
24
+ * each impl's real auth resolution; a conformance table given the live mount
25
+ * (`live_rpc_endpoints`) fires the same refusals through the auth rows
26
+ * `generate_rpc_auth_conformance_cases` generates for them.
24
27
  *
25
- * For every backdoor method, three principals:
28
+ * **The declaration.** A backend states which it mounts in
29
+ * `capabilities.testing_backdoors`, and the suite holds it to that: each known
30
+ * backdoor the declaration leaves out is sent anonymously and must answer
31
+ * `method_not_found` (404) — both spines look a method up before they
32
+ * authenticate the caller, so an unmounted method answers that whatever the
33
+ * credential — and each declared one runs the rows below, whose anonymous row
34
+ * (a 401, not `method_not_found`) proves it mounted. A wrong declaration fails
35
+ * either way, so the suites that skip on an undeclared backdoor
36
+ * (`describe_spine_cross_suites`) skip only what the backend truly lacks. The
37
+ * check runs on every backend, one mounting none of them included.
38
+ *
39
+ * For every declared backdoor, and each `extra_methods` seam (a consumer's own
40
+ * daemon-token action), three principals:
26
41
  *
27
42
  * - **anonymous** (no credential) → `401` (pre-authorization auth refuses an
28
43
  * account-less caller before anything else).
@@ -53,13 +68,13 @@ import '../assert_dev_env.js';
53
68
  * on both impls. Cited property: `security.md` §Test Backdoor Actions
54
69
  * (daemon-token-gated, off-surface, DEV-excluded).
55
70
  *
56
- * Cross-process only — the `_testing_*` actions are mounted on the spawned
57
- * binary, not the in-process app — like the ws/sse suites. Wire from a
58
- * `*.cross.test.ts`. Requires the standard `_testing_*` actions mounted (the
59
- * same precondition `default_cross_process_setup` already imposes for its
60
- * per-test `_testing_reset`); the HTTP cases are ungated, since every cross
61
- * backend mounts them, and the WS cases run when `ws` is passed — for a
62
- * backend that also serves them on its WS endpoint.
71
+ * The credential rows run cross-process only — the `_testing_*` actions are
72
+ * mounted on the spawned binary, not the in-process app — like the ws/sse
73
+ * suites; there, wire from a `*.cross.test.ts`, whose setup fires
74
+ * `_testing_reset`, so the backend must mount that one. In-process, an app
75
+ * mounting none declares none, and the suite runs the declaration rows alone,
76
+ * one per known backdoor. The WS cases run when `ws` is passed — for a
77
+ * backend that also serves its backdoors on its WS endpoint.
63
78
  *
64
79
  * @module
65
80
  */
@@ -67,46 +82,49 @@ import { describe, test, assert } from 'vitest';
67
82
  import { ERROR_CREDENTIAL_TYPE_REQUIRED } from '../../http/error_schemas.js';
68
83
  import { JSONRPC_ERROR_CODES } from '../../http/jsonrpc_errors.js';
69
84
  import { rpc_call } from '../rpc_helpers.js';
70
- import { create_admitted_ws_transport } from '../transports/ws_transport.js';
85
+ import { TESTING_METHOD_PREFIX } from '../surface_invariants.js';
71
86
  import { is_response_for } from '../transports/ws_client.js';
72
87
  import { test_if } from './capabilities.js';
73
- import { SPINE_RPC_PATH } from './spine_surface_constants.js';
88
+ import { SPINE_RPC_PATH, TESTING_BACKDOOR_METHODS } from './spine_surface_constants.js';
89
+ import { open_session_ws } from './ws_endpoint.js';
74
90
  /** A well-formed UUID that never names a real row. */
75
91
  const NIL_UUID = '00000000-0000-0000-0000-000000000000';
76
92
  /**
77
- * The backdoor methods + a **valid** params payload each (so the
78
- * session/bearer cases reach the 403 credential gate rather than a 400 on
79
- * input validation). The handlers never run — the gate refuses first.
93
+ * A **valid** params payload for each known backdoor (so the session/bearer
94
+ * cases reach the 403 credential gate rather than a 400 on input validation).
95
+ * The handlers never run — the gate refuses first. Keyed by
96
+ * `TestingBackdoorMethod`, so a method added to `TESTING_BACKDOOR_METHODS`
97
+ * fails typecheck here until it has its params.
80
98
  */
81
- const backdoor_methods = [
82
- { method: '_testing_reset', params: {} },
99
+ const BACKDOOR_PARAMS = {
100
+ _testing_reset: {},
83
101
  // The audit barrier — its input is void, so the call carries no params.
84
- { method: '_testing_drain_effects', params: undefined },
85
- { method: '_testing_mint_session', params: { account_id: NIL_UUID, expires_in_seconds: -60 } },
86
- { method: '_testing_put_fact', params: { content: 'backdoor-probe' } },
102
+ _testing_drain_effects: undefined,
103
+ _testing_mint_session: { account_id: NIL_UUID, expires_in_seconds: -60 },
104
+ _testing_put_fact: { content: 'backdoor-probe' },
87
105
  // An empty burst — valid input, so it clears the 400 phase; a refused
88
106
  // caller never reaches the handler that would queue it.
89
- { method: '_testing_flood_notifications', params: { count: 0, size: 0 } },
107
+ _testing_flood_notifications: { count: 0, size: 0 },
90
108
  // The schema-dump read — `exclude_tables` is optional, so `{}` is valid
91
109
  // and clears the 400 phase like the writes above.
92
- { method: '_testing_schema_snapshot', params: {} },
110
+ _testing_schema_snapshot: {},
93
111
  // The migration-tracker-dump read — input is an empty strict object, so `{}`
94
112
  // is valid and clears the 400 phase, reaching the credential gate like the rest.
95
- { method: '_testing_migration_tracker', params: {} },
113
+ _testing_migration_tracker: {},
96
114
  // The RPC-registry-dump read — input is an empty strict object, so `{}` is
97
115
  // valid and clears the 400 phase, reaching the credential gate like the rest.
98
- { method: '_testing_action_manifest', params: {} },
116
+ _testing_action_manifest: {},
99
117
  // The origin conformance probe — a valid `{patterns, origin}` pair, so it
100
118
  // clears the 400 phase like the rest.
101
- { method: '_testing_origin_check', params: { patterns: 'http://localhost:*', origin: null } },
119
+ _testing_origin_check: { patterns: 'http://localhost:*', origin: null },
102
120
  // The credential-expiry rewrite — a valid `{account_id, seconds}` pair (a
103
121
  // syntactically valid UUID; no row needs to match), so it clears the 400
104
122
  // phase like the rest.
105
- {
106
- method: '_testing_shorten_credential_expiry',
107
- params: { account_id: '00000000-0000-4000-8000-000000000000', seconds: 30 }
123
+ _testing_shorten_credential_expiry: {
124
+ account_id: '00000000-0000-4000-8000-000000000000',
125
+ seconds: 30
108
126
  }
109
- ];
127
+ };
110
128
  const principals = [
111
129
  {
112
130
  name: 'anonymous',
@@ -137,11 +155,89 @@ const principals = [
137
155
  })
138
156
  }
139
157
  ];
158
+ /**
159
+ * The known backdoors a backend declares, checked against the known list,
160
+ * and its extra seams, checked against the `_testing_` prefix and the list.
161
+ *
162
+ * @throws Error - on a declared method that isn't a known backdoor, an extra
163
+ * method outside the `_testing_` namespace or naming a known backdoor, or a
164
+ * duplicate
165
+ */
166
+ const resolve_backdoor_probes = (declared, extra_methods) => {
167
+ const known = new Set(TESTING_BACKDOOR_METHODS);
168
+ const seen = new Set();
169
+ for (const method of declared) {
170
+ if (!known.has(method)) {
171
+ throw new Error(`describe_testing_backdoor_cross_tests: capabilities.testing_backdoors declares ` +
172
+ `'${method}', which is not in TESTING_BACKDOOR_METHODS — pass a consumer seam as extra_methods`);
173
+ }
174
+ if (seen.has(method)) {
175
+ throw new Error(`describe_testing_backdoor_cross_tests: capabilities.testing_backdoors declares '${method}' twice`);
176
+ }
177
+ seen.add(method);
178
+ }
179
+ for (const { method } of extra_methods) {
180
+ if (!method.startsWith(TESTING_METHOD_PREFIX) || known.has(method)) {
181
+ throw new Error(`describe_testing_backdoor_cross_tests: extra method '${method}' must start with ` +
182
+ `'${TESTING_METHOD_PREFIX}' and not be a known backdoor (declare those in capabilities.testing_backdoors)`);
183
+ }
184
+ if (seen.has(method)) {
185
+ throw new Error(`describe_testing_backdoor_cross_tests: extra method '${method}' is listed twice`);
186
+ }
187
+ seen.add(method);
188
+ }
189
+ return [
190
+ ...TESTING_BACKDOOR_METHODS.filter((method) => declared.includes(method)).map((method) => ({
191
+ method,
192
+ params: BACKDOOR_PARAMS[method]
193
+ })),
194
+ ...extra_methods
195
+ ];
196
+ };
197
+ /**
198
+ * Register the backdoor suite: the declaration check over every known
199
+ * backdoor, then the refused-principal rows over the mounted ones.
200
+ *
201
+ * @param options - the fixture, the backend's capabilities, and the optional
202
+ * WS target and extra seams
203
+ * @throws Error - on a declaration or extra method `resolve_backdoor_probes` refuses
204
+ */
140
205
  export const describe_testing_backdoor_cross_tests = (options) => {
141
- const { setup_test, ws } = options;
206
+ const { setup_test, capabilities, ws, extra_methods = [] } = options;
142
207
  const rpc_path = options.rpc_path ?? SPINE_RPC_PATH;
208
+ const declared = capabilities.testing_backdoors;
209
+ const probes = resolve_backdoor_probes(declared, extra_methods);
210
+ // a declared backdoor's mount is pinned by its anonymous row below (a 401,
211
+ // not `method_not_found`); an undeclared one must not be mounted, so a
212
+ // backend can't mount one its declaration leaves out
213
+ const undeclared = TESTING_BACKDOOR_METHODS.filter((method) => !declared.includes(method));
214
+ // vitest fails a describe holding no test, so a full declaration registers none
215
+ if (undeclared.length > 0) {
216
+ describe('testing backdoor declaration', () => {
217
+ for (const method of undeclared) {
218
+ test(`${method} is undeclared → method_not_found`, async () => {
219
+ const fixture = await setup_test();
220
+ const res = await rpc_call({
221
+ app: fixture.fresh_transport(),
222
+ path: rpc_path,
223
+ method,
224
+ params: BACKDOOR_PARAMS[method]
225
+ });
226
+ assert.ok(!res.ok, `${method}: undeclared in capabilities.testing_backdoors, but the call succeeded`);
227
+ if (!res.ok) {
228
+ assert.strictEqual(res.error.code, JSONRPC_ERROR_CODES.method_not_found, `${method}: undeclared in capabilities.testing_backdoors, but it answers ` +
229
+ `${res.status} (${res.error.code}) — the backend mounts it, so declare it`);
230
+ }
231
+ assert.strictEqual(res.status, 404, `${method}: status`);
232
+ });
233
+ }
234
+ });
235
+ }
236
+ // none declared and no extra seam: no rows, and vitest fails an empty describe
237
+ if (probes.length === 0)
238
+ return;
143
239
  describe('testing backdoor credential gate parity', () => {
144
- for (const { method, params } of backdoor_methods) {
240
+ for (const { method, params } of probes) {
145
241
  for (const principal of principals) {
146
242
  test(`${method} rejects ${principal.name} → ${principal.status}`, async () => {
147
243
  const fixture = await setup_test();
@@ -156,9 +252,10 @@ export const describe_testing_backdoor_cross_tests = (options) => {
156
252
  });
157
253
  const label = `${method} ${principal.name}`;
158
254
  assert.ok(!res.ok, `${label}: expected denial (${principal.status}) but the call succeeded`);
159
- assert.strictEqual(res.status, principal.status, `${label}: status`);
160
255
  // `!res.ok` narrows `res` to the error variant for `res.error`.
161
256
  if (!res.ok) {
257
+ assert.notStrictEqual(res.error.code, JSONRPC_ERROR_CODES.method_not_found, `${label}: declared but not mounted — the backend answers method_not_found`);
258
+ assert.strictEqual(res.status, principal.status, `${label}: status`);
162
259
  assert.strictEqual(res.error.code, principal.code, `${label}: error.code`);
163
260
  if (principal.reason !== undefined) {
164
261
  const reason = res.error.data?.reason;
@@ -168,15 +265,10 @@ export const describe_testing_backdoor_cross_tests = (options) => {
168
265
  });
169
266
  }
170
267
  }
171
- for (const { method, params } of backdoor_methods) {
268
+ for (const { method, params } of probes) {
172
269
  test_if(ws !== undefined, `${method} over a session socket → forbidden ${ERROR_CREDENTIAL_TYPE_REQUIRED}`, async () => {
173
270
  const fixture = await setup_test();
174
- const client = await create_admitted_ws_transport({
175
- base_url: ws.base_url,
176
- ws_path: ws.ws_path,
177
- cookies: fixture.transport.cookies(),
178
- origin: ws.origin
179
- });
271
+ const client = await open_session_ws(ws, fixture, { admitted: true });
180
272
  try {
181
273
  const id = `backdoor_${method}`;
182
274
  await client.send({ jsonrpc: '2.0', id, method, params });