@fuzdev/fuz_app 0.147.0 → 0.148.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 (273) hide show
  1. package/dist/actions/CLAUDE.md +6 -4
  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/perform_action.js +1 -1
  6. package/dist/auth/cell_action_specs.d.ts +3 -1
  7. package/dist/auth/cell_action_specs.d.ts.map +1 -1
  8. package/dist/auth/cell_action_specs.js +5 -5
  9. package/dist/auth/cell_actions.d.ts.map +1 -1
  10. package/dist/auth/cell_actions.js +2 -3
  11. package/dist/auth/cell_data_schema.d.ts +1 -1
  12. package/dist/auth/cell_data_schema.js +1 -1
  13. package/dist/auth/cell_field_action_specs.d.ts +4 -3
  14. package/dist/auth/cell_field_action_specs.d.ts.map +1 -1
  15. package/dist/auth/cell_field_action_specs.js +5 -6
  16. package/dist/auth/cell_field_actions.d.ts.map +1 -1
  17. package/dist/auth/cell_field_actions.js +8 -1
  18. package/dist/auth/cell_item_action_specs.d.ts +4 -2
  19. package/dist/auth/cell_item_action_specs.d.ts.map +1 -1
  20. package/dist/auth/cell_item_action_specs.js +5 -5
  21. package/dist/auth/cell_item_actions.d.ts.map +1 -1
  22. package/dist/auth/cell_item_actions.js +8 -1
  23. package/dist/auth/role_grant_offer_action_specs.d.ts +2 -0
  24. package/dist/auth/role_grant_offer_action_specs.d.ts.map +1 -1
  25. package/dist/auth/role_grant_offer_action_specs.js +3 -1
  26. package/dist/primitive_schemas.d.ts +1 -1
  27. package/dist/primitive_schemas.d.ts.map +1 -1
  28. package/dist/primitive_schemas.js +2 -1
  29. package/dist/schema_meta.d.ts +20 -0
  30. package/dist/schema_meta.d.ts.map +1 -1
  31. package/dist/schema_meta.js +7 -1
  32. package/dist/testing/CLAUDE.md +720 -114
  33. package/dist/testing/admin_integration.d.ts.map +1 -1
  34. package/dist/testing/admin_integration.js +73 -5
  35. package/dist/testing/adversarial_input.d.ts +0 -47
  36. package/dist/testing/adversarial_input.d.ts.map +1 -1
  37. package/dist/testing/adversarial_input.js +4 -340
  38. package/dist/testing/adversarial_input_cases.d.ts +64 -0
  39. package/dist/testing/adversarial_input_cases.d.ts.map +1 -0
  40. package/dist/testing/adversarial_input_cases.js +348 -0
  41. package/dist/testing/audit_completeness.d.ts.map +1 -1
  42. package/dist/testing/audit_completeness.js +24 -20
  43. package/dist/testing/audit_drift_guard.d.ts +27 -1
  44. package/dist/testing/audit_drift_guard.d.ts.map +1 -1
  45. package/dist/testing/audit_drift_guard.js +50 -0
  46. package/dist/testing/cross_backend/account_lifecycle.d.ts.map +1 -1
  47. package/dist/testing/cross_backend/account_lifecycle.js +29 -12
  48. package/dist/testing/cross_backend/actor_lookup.d.ts.map +1 -1
  49. package/dist/testing/cross_backend/actor_lookup.js +7 -25
  50. package/dist/testing/cross_backend/app_settings.d.ts.map +1 -1
  51. package/dist/testing/cross_backend/app_settings.js +4 -6
  52. package/dist/testing/cross_backend/audit_cross_helpers.d.ts +51 -0
  53. package/dist/testing/cross_backend/audit_cross_helpers.d.ts.map +1 -0
  54. package/dist/testing/cross_backend/audit_cross_helpers.js +78 -0
  55. package/dist/testing/cross_backend/backend_config.d.ts +2 -1
  56. package/dist/testing/cross_backend/backend_config.d.ts.map +1 -1
  57. package/dist/testing/cross_backend/body_size.d.ts +6 -0
  58. package/dist/testing/cross_backend/body_size.d.ts.map +1 -1
  59. package/dist/testing/cross_backend/body_size.js +26 -44
  60. package/dist/testing/cross_backend/body_size_smuggling.d.ts +5 -0
  61. package/dist/testing/cross_backend/body_size_smuggling.d.ts.map +1 -1
  62. package/dist/testing/cross_backend/body_size_smuggling.js +7 -14
  63. package/dist/testing/cross_backend/build_test_backend_paths.d.ts +3 -1
  64. package/dist/testing/cross_backend/build_test_backend_paths.d.ts.map +1 -1
  65. package/dist/testing/cross_backend/capabilities.d.ts +55 -59
  66. package/dist/testing/cross_backend/capabilities.d.ts.map +1 -1
  67. package/dist/testing/cross_backend/capabilities.js +20 -23
  68. package/dist/testing/cross_backend/cargo_binary.d.ts +70 -0
  69. package/dist/testing/cross_backend/cargo_binary.d.ts.map +1 -0
  70. package/dist/testing/cross_backend/cargo_binary.js +148 -0
  71. package/dist/testing/cross_backend/cell_crud.d.ts.map +1 -1
  72. package/dist/testing/cross_backend/cell_crud.js +57 -1
  73. package/dist/testing/cross_backend/cell_gated_create.d.ts +0 -60
  74. package/dist/testing/cross_backend/cell_gated_create.d.ts.map +1 -1
  75. package/dist/testing/cross_backend/cell_gated_create.js +9 -487
  76. package/dist/testing/cross_backend/cell_grant_role.d.ts +14 -2
  77. package/dist/testing/cross_backend/cell_grant_role.d.ts.map +1 -1
  78. package/dist/testing/cross_backend/cell_grant_role.js +22 -12
  79. package/dist/testing/cross_backend/cell_moderate.d.ts +66 -0
  80. package/dist/testing/cross_backend/cell_moderate.d.ts.map +1 -0
  81. package/dist/testing/cross_backend/cell_moderate.js +511 -0
  82. package/dist/testing/cross_backend/cell_ref_admission.d.ts.map +1 -1
  83. package/dist/testing/cross_backend/cell_ref_admission.js +1 -1
  84. package/dist/testing/cross_backend/cell_relations.d.ts.map +1 -1
  85. package/dist/testing/cross_backend/cell_relations.js +40 -19
  86. package/dist/testing/cross_backend/conformance_case.d.ts +43 -4
  87. package/dist/testing/cross_backend/conformance_case.d.ts.map +1 -1
  88. package/dist/testing/cross_backend/conformance_case.js +29 -1
  89. package/dist/testing/cross_backend/conformance_rpc_auth.d.ts +93 -0
  90. package/dist/testing/cross_backend/conformance_rpc_auth.d.ts.map +1 -0
  91. package/dist/testing/cross_backend/conformance_rpc_auth.js +125 -0
  92. package/dist/testing/cross_backend/conformance_table.d.ts +144 -4
  93. package/dist/testing/cross_backend/conformance_table.d.ts.map +1 -1
  94. package/dist/testing/cross_backend/conformance_table.js +297 -65
  95. package/dist/testing/cross_backend/cookie_attributes.d.ts.map +1 -1
  96. package/dist/testing/cross_backend/cookie_attributes.js +3 -2
  97. package/dist/testing/cross_backend/create_cross_backend_global_setup.d.ts +38 -5
  98. package/dist/testing/cross_backend/create_cross_backend_global_setup.d.ts.map +1 -1
  99. package/dist/testing/cross_backend/create_cross_backend_global_setup.js +24 -3
  100. package/dist/testing/cross_backend/create_dual_spawn_global_setup.d.ts +5 -5
  101. package/dist/testing/cross_backend/create_dual_spawn_global_setup.d.ts.map +1 -1
  102. package/dist/testing/cross_backend/credential_deadline.d.ts +10 -6
  103. package/dist/testing/cross_backend/credential_deadline.d.ts.map +1 -1
  104. package/dist/testing/cross_backend/credential_deadline.js +32 -31
  105. package/dist/testing/cross_backend/credential_header_robustness.d.ts.map +1 -1
  106. package/dist/testing/cross_backend/credential_header_robustness.js +4 -6
  107. package/dist/testing/cross_backend/{cell_cross_helpers.d.ts → cross_rpc.d.ts} +12 -2
  108. package/dist/testing/cross_backend/cross_rpc.d.ts.map +1 -0
  109. package/dist/testing/cross_backend/{cell_cross_helpers.js → cross_rpc.js} +31 -7
  110. package/dist/testing/cross_backend/default_backend_configs.d.ts +56 -61
  111. package/dist/testing/cross_backend/default_backend_configs.d.ts.map +1 -1
  112. package/dist/testing/cross_backend/default_backend_configs.js +97 -91
  113. package/dist/testing/cross_backend/default_spine_surface.d.ts.map +1 -1
  114. package/dist/testing/cross_backend/default_spine_surface.js +2 -2
  115. package/dist/testing/cross_backend/differential.d.ts +126 -0
  116. package/dist/testing/cross_backend/differential.d.ts.map +1 -0
  117. package/dist/testing/cross_backend/differential.js +201 -0
  118. package/dist/testing/cross_backend/differential_normalize.d.ts +150 -0
  119. package/dist/testing/cross_backend/differential_normalize.d.ts.map +1 -0
  120. package/dist/testing/cross_backend/differential_normalize.js +153 -0
  121. package/dist/testing/cross_backend/fact_serving.d.ts.map +1 -1
  122. package/dist/testing/cross_backend/fact_serving.js +27 -17
  123. package/dist/testing/cross_backend/full_spine_mount.d.ts +15 -0
  124. package/dist/testing/cross_backend/full_spine_mount.d.ts.map +1 -1
  125. package/dist/testing/cross_backend/full_spine_mount.js +55 -1
  126. package/dist/testing/cross_backend/identity_parity.d.ts.map +1 -1
  127. package/dist/testing/cross_backend/identity_parity.js +6 -5
  128. package/dist/testing/cross_backend/in_process_setup.d.ts +12 -2
  129. package/dist/testing/cross_backend/in_process_setup.d.ts.map +1 -1
  130. package/dist/testing/cross_backend/in_process_setup.js +10 -7
  131. package/dist/testing/cross_backend/login_security.d.ts.map +1 -1
  132. package/dist/testing/cross_backend/login_security.js +13 -18
  133. package/dist/testing/cross_backend/origin.js +1 -1
  134. package/dist/testing/cross_backend/origin_conformance.js +1 -1
  135. package/dist/testing/cross_backend/origin_scope.d.ts +6 -0
  136. package/dist/testing/cross_backend/origin_scope.d.ts.map +1 -1
  137. package/dist/testing/cross_backend/origin_scope.js +13 -12
  138. package/dist/testing/cross_backend/peer_ping_ws.d.ts +2 -5
  139. package/dist/testing/cross_backend/peer_ping_ws.d.ts.map +1 -1
  140. package/dist/testing/cross_backend/peer_ping_ws.js +14 -24
  141. package/dist/testing/cross_backend/postgres_database.d.ts +85 -0
  142. package/dist/testing/cross_backend/postgres_database.d.ts.map +1 -0
  143. package/dist/testing/cross_backend/postgres_database.js +140 -0
  144. package/dist/testing/cross_backend/provided_context.d.ts +28 -0
  145. package/dist/testing/cross_backend/provided_context.d.ts.map +1 -0
  146. package/dist/testing/cross_backend/provided_context.js +35 -0
  147. package/dist/testing/cross_backend/query_shape.d.ts.map +1 -1
  148. package/dist/testing/cross_backend/query_shape.js +10 -12
  149. package/dist/testing/cross_backend/ready.js +2 -2
  150. package/dist/testing/cross_backend/revocation_drivers.d.ts +4 -3
  151. package/dist/testing/cross_backend/revocation_drivers.d.ts.map +1 -1
  152. package/dist/testing/cross_backend/revocation_drivers.js +1 -1
  153. package/dist/testing/cross_backend/role_grant_cross_helpers.d.ts +3 -2
  154. package/dist/testing/cross_backend/role_grant_cross_helpers.d.ts.map +1 -1
  155. package/dist/testing/cross_backend/role_grant_offer_lifecycle.d.ts +13 -0
  156. package/dist/testing/cross_backend/role_grant_offer_lifecycle.d.ts.map +1 -0
  157. package/dist/testing/cross_backend/role_grant_offer_lifecycle.js +203 -0
  158. package/dist/testing/cross_backend/role_grant_offer_notification_ws.d.ts +2 -5
  159. package/dist/testing/cross_backend/role_grant_offer_notification_ws.d.ts.map +1 -1
  160. package/dist/testing/cross_backend/role_grant_offer_notification_ws.js +203 -111
  161. package/dist/testing/cross_backend/role_grant_participation.d.ts +13 -0
  162. package/dist/testing/cross_backend/role_grant_participation.d.ts.map +1 -1
  163. package/dist/testing/cross_backend/role_grant_participation.js +32 -21
  164. package/dist/testing/cross_backend/role_grant_role_grammar.d.ts.map +1 -1
  165. package/dist/testing/cross_backend/role_grant_role_grammar.js +6 -9
  166. package/dist/testing/cross_backend/rpc_adversarial.d.ts +38 -0
  167. package/dist/testing/cross_backend/rpc_adversarial.d.ts.map +1 -0
  168. package/dist/testing/cross_backend/rpc_adversarial.js +292 -0
  169. package/dist/testing/cross_backend/rpc_success_fixtures.d.ts +24 -0
  170. package/dist/testing/cross_backend/rpc_success_fixtures.d.ts.map +1 -0
  171. package/dist/testing/cross_backend/rpc_success_fixtures.js +124 -0
  172. package/dist/testing/cross_backend/rust_spine_consumer_surface.d.ts +101 -0
  173. package/dist/testing/cross_backend/rust_spine_consumer_surface.d.ts.map +1 -0
  174. package/dist/testing/cross_backend/rust_spine_consumer_surface.js +113 -0
  175. package/dist/testing/cross_backend/rust_spine_stub_backend_config.d.ts +10 -0
  176. package/dist/testing/cross_backend/rust_spine_stub_backend_config.d.ts.map +1 -1
  177. package/dist/testing/cross_backend/rust_spine_stub_backend_config.js +27 -18
  178. package/dist/testing/cross_backend/session_cap.d.ts +9 -8
  179. package/dist/testing/cross_backend/session_cap.d.ts.map +1 -1
  180. package/dist/testing/cross_backend/session_cap.js +9 -4
  181. package/dist/testing/cross_backend/session_cookie_codec.js +1 -1
  182. package/dist/testing/cross_backend/setup.d.ts +56 -54
  183. package/dist/testing/cross_backend/setup.d.ts.map +1 -1
  184. package/dist/testing/cross_backend/setup.js +29 -29
  185. package/dist/testing/cross_backend/simple_request.d.ts.map +1 -1
  186. package/dist/testing/cross_backend/simple_request.js +4 -4
  187. package/dist/testing/cross_backend/spawn_backend.d.ts +59 -10
  188. package/dist/testing/cross_backend/spawn_backend.d.ts.map +1 -1
  189. package/dist/testing/cross_backend/spawn_backend.js +219 -60
  190. package/dist/testing/cross_backend/spine_suites.d.ts +231 -0
  191. package/dist/testing/cross_backend/spine_suites.d.ts.map +1 -0
  192. package/dist/testing/cross_backend/spine_suites.js +626 -0
  193. package/dist/testing/cross_backend/spine_surface_constants.d.ts +29 -0
  194. package/dist/testing/cross_backend/spine_surface_constants.d.ts.map +1 -1
  195. package/dist/testing/cross_backend/spine_surface_constants.js +29 -0
  196. package/dist/testing/cross_backend/sse_round_trip.d.ts.map +1 -1
  197. package/dist/testing/cross_backend/sse_round_trip.js +3 -4
  198. package/dist/testing/cross_backend/standard.d.ts +18 -1
  199. package/dist/testing/cross_backend/standard.d.ts.map +1 -1
  200. package/dist/testing/cross_backend/standard.js +2 -0
  201. package/dist/testing/cross_backend/test_cell_gated_create_authorize.d.ts +24 -0
  202. package/dist/testing/cross_backend/test_cell_gated_create_authorize.d.ts.map +1 -1
  203. package/dist/testing/cross_backend/test_cell_gated_create_authorize.js +15 -0
  204. package/dist/testing/cross_backend/testing_backdoor.d.ts +2 -8
  205. package/dist/testing/cross_backend/testing_backdoor.d.ts.map +1 -1
  206. package/dist/testing/cross_backend/testing_backdoor.js +7 -10
  207. package/dist/testing/cross_backend/testing_reset_actions.d.ts +3 -2
  208. package/dist/testing/cross_backend/testing_reset_actions.d.ts.map +1 -1
  209. package/dist/testing/cross_backend/testing_reset_actions.js +8 -4
  210. package/dist/testing/cross_backend/testing_server_bun.js +1 -1
  211. package/dist/testing/cross_backend/token_lifetime.js +1 -1
  212. package/dist/testing/cross_backend/token_scope_surface.d.ts.map +1 -1
  213. package/dist/testing/cross_backend/token_scope_surface.js +9 -13
  214. package/dist/testing/cross_backend/transport_composition.d.ts +26 -2
  215. package/dist/testing/cross_backend/transport_composition.d.ts.map +1 -1
  216. package/dist/testing/cross_backend/transport_composition.js +81 -51
  217. package/dist/testing/cross_backend/ts_spine_backend_config.d.ts +8 -0
  218. package/dist/testing/cross_backend/ts_spine_backend_config.d.ts.map +1 -1
  219. package/dist/testing/cross_backend/ts_spine_backend_config.js +17 -10
  220. package/dist/testing/cross_backend/ws_action_rate_limit.d.ts +2 -5
  221. package/dist/testing/cross_backend/ws_action_rate_limit.d.ts.map +1 -1
  222. package/dist/testing/cross_backend/ws_action_rate_limit.js +8 -14
  223. package/dist/testing/cross_backend/ws_connection_cap.d.ts +4 -9
  224. package/dist/testing/cross_backend/ws_connection_cap.d.ts.map +1 -1
  225. package/dist/testing/cross_backend/ws_connection_cap.js +11 -12
  226. package/dist/testing/cross_backend/ws_endpoint.d.ts +52 -0
  227. package/dist/testing/cross_backend/ws_endpoint.d.ts.map +1 -0
  228. package/dist/testing/cross_backend/ws_endpoint.js +54 -0
  229. package/dist/testing/cross_backend/ws_inbound_dispatch.d.ts +2 -5
  230. package/dist/testing/cross_backend/ws_inbound_dispatch.d.ts.map +1 -1
  231. package/dist/testing/cross_backend/ws_inbound_dispatch.js +9 -15
  232. package/dist/testing/cross_backend/ws_outbound_overflow.d.ts +2 -7
  233. package/dist/testing/cross_backend/ws_outbound_overflow.d.ts.map +1 -1
  234. package/dist/testing/cross_backend/ws_outbound_overflow.js +5 -9
  235. package/dist/testing/cross_backend/ws_role_gated.d.ts +4 -5
  236. package/dist/testing/cross_backend/ws_role_gated.d.ts.map +1 -1
  237. package/dist/testing/cross_backend/ws_role_gated.js +12 -21
  238. package/dist/testing/cross_backend/ws_round_trip.d.ts +12 -9
  239. package/dist/testing/cross_backend/ws_round_trip.d.ts.map +1 -1
  240. package/dist/testing/cross_backend/ws_round_trip.js +29 -34
  241. package/dist/testing/db_entities.d.ts +16 -3
  242. package/dist/testing/db_entities.d.ts.map +1 -1
  243. package/dist/testing/db_entities.js +28 -5
  244. package/dist/testing/integration_helpers.d.ts +61 -2
  245. package/dist/testing/integration_helpers.d.ts.map +1 -1
  246. package/dist/testing/integration_helpers.js +75 -18
  247. package/dist/testing/round_trip.d.ts +17 -0
  248. package/dist/testing/round_trip.d.ts.map +1 -1
  249. package/dist/testing/round_trip.js +67 -24
  250. package/dist/testing/rpc_attack_surface.d.ts.map +1 -1
  251. package/dist/testing/rpc_attack_surface.js +13 -138
  252. package/dist/testing/rpc_envelope_cases.d.ts +111 -0
  253. package/dist/testing/rpc_envelope_cases.d.ts.map +1 -0
  254. package/dist/testing/rpc_envelope_cases.js +240 -0
  255. package/dist/testing/rpc_helpers.d.ts +31 -0
  256. package/dist/testing/rpc_helpers.d.ts.map +1 -1
  257. package/dist/testing/rpc_helpers.js +35 -14
  258. package/dist/testing/rpc_round_trip.d.ts +62 -6
  259. package/dist/testing/rpc_round_trip.d.ts.map +1 -1
  260. package/dist/testing/rpc_round_trip.js +151 -39
  261. package/dist/testing/schema_generators.d.ts.map +1 -1
  262. package/dist/testing/schema_generators.js +22 -2
  263. package/dist/testing/standard.d.ts +26 -0
  264. package/dist/testing/standard.d.ts.map +1 -1
  265. package/dist/testing/standard.js +4 -1
  266. package/dist/testing/transports/raw_http.d.ts +21 -0
  267. package/dist/testing/transports/raw_http.d.ts.map +1 -1
  268. package/dist/testing/transports/raw_http.js +30 -0
  269. package/package.json +6 -4
  270. package/dist/testing/cross_backend/actor_search.d.ts +0 -6
  271. package/dist/testing/cross_backend/actor_search.d.ts.map +0 -1
  272. package/dist/testing/cross_backend/actor_search.js +0 -90
  273. package/dist/testing/cross_backend/cell_cross_helpers.d.ts.map +0 -1
@@ -0,0 +1,626 @@
1
+ import '../assert_dev_env.js';
2
+ /**
3
+ * One call that runs every shipped single-backend cross suite a backend's
4
+ * capabilities admit — `describe_spine_cross_suites(handle, options)`.
5
+ *
6
+ * A consumer's cross project otherwise wires one file per upstream suite, so a
7
+ * suite added here never reaches it unless someone adds the file. The one-call
8
+ * form runs `SUITE_NAMES` — the closed registry of shipped suites, each named by
9
+ * its module — and builds every suite's options from the handle: the paths,
10
+ * cookie name and capabilities from `handle.config` (`to_cross_suite_options`),
11
+ * the daemon token from the handle, and each suite's `setup_test` through
12
+ * `default_cross_process_setup` with whatever seeding that suite needs (the
13
+ * multi-actor keeper, the offer grantor, the cell role holder). Each suite
14
+ * gates its own cases on the capabilities, so a backend runs what it mounts.
15
+ *
16
+ * **Options are additive.**
17
+ *
18
+ * - `exclude` names a suite with the reason it can't run on this backend; the
19
+ * reason is required and shows in the run as a skipped test, so a skip is
20
+ * stated in code and visible in the report.
21
+ * - `overrides` replaces a suite's derived options, field by field (a shallow
22
+ * merge over what the handle gives) — a role list the backend's WS upgrade
23
+ * requires, an `xfail` for a tracked divergence, a narrower capability set.
24
+ * An entry can be a function of the derived options instead, for a change
25
+ * built on a derived value. A required option the merge leaves `undefined`
26
+ * throws at collection.
27
+ * - `rpc_success_fixtures` / `rpc_skip_methods` / `rpc_input_overrides` go to
28
+ * the standard bundle's RPC round-trip.
29
+ * - `ws_required_roles` names the roles the backend's WS upgrade requires, so the
30
+ * suites that open sockets for accounts they create give them those roles.
31
+ * - `suite_roles` names the roles the role-shaped suites use when the backend's
32
+ * registry lacks the spine's own (`cell_editor`, `participant`); the call
33
+ * seeds the holder each needs.
34
+ *
35
+ * **Inputs the handle doesn't carry.** The declared surface (`surface_source`,
36
+ * `session_options`, `rpc_endpoints`, `roles`) is a required option. Paths and
37
+ * roles that name what the reference spines mount (the role-gated WS endpoint
38
+ * and its roles) default to the `SPINE_*` constants, and a suite whose
39
+ * capability flag is off never reaches them. Anything else a suite needs comes
40
+ * from the handle when it can (`session_cookie_codec`'s `cookie_keys` from the
41
+ * config's `SECRET_FUZ_COOKIE_KEYS`), else from `overrides`; when neither has
42
+ * it, the call throws naming the suite — provide it or exclude the suite.
43
+ *
44
+ * **Not in the one call** (`STANDALONE_CROSS_SUITES`, with the reasons): the
45
+ * suites that need two handles (the differential), a backend spawned with live
46
+ * limiters (`login_security`, `ws_action_rate_limit` — the standard suites would
47
+ * exhaust them), and the conformance runner, which runs the consumer's own
48
+ * cases. Each keeps its own entry point.
49
+ *
50
+ * Suites are registered without a wrapping `describe`, so their test names are
51
+ * the same as when each is called on its own.
52
+ *
53
+ * @module
54
+ */
55
+ import { describe, test } from 'vitest';
56
+ import { ROLE_KEEPER, ROLE_ADMIN } from '../../auth/role_schema.js';
57
+ import { resolve_rpc_endpoints_for_setup } from '../rpc_helpers.js';
58
+ import { describe_account_lifecycle_cross_tests } from './account_lifecycle.js';
59
+ import { describe_actor_lookup_cross_tests } from './actor_lookup.js';
60
+ import { describe_app_settings_cross_tests } from './app_settings.js';
61
+ import { describe_body_size_cross_tests } from './body_size.js';
62
+ import { describe_body_size_smuggling_cross_tests } from './body_size_smuggling.js';
63
+ import { describe_cell_crud_cross_tests } from './cell_crud.js';
64
+ import { describe_cell_gated_create_cross_tests } from './cell_gated_create.js';
65
+ import { CELL_EDITOR_ROLE, CELL_ROLE_HOLDER_USERNAME, describe_cell_grant_role_cross_tests } from './cell_grant_role.js';
66
+ import { describe_cell_moderate_cross_tests } from './cell_moderate.js';
67
+ import { describe_cell_ref_admission_cross_tests } from './cell_ref_admission.js';
68
+ import { describe_cell_relations_cross_tests } from './cell_relations.js';
69
+ import { describe_cookie_attributes_cross_tests } from './cookie_attributes.js';
70
+ import { describe_credential_deadline_cross_tests } from './credential_deadline.js';
71
+ import { describe_credential_header_robustness_cross_tests } from './credential_header_robustness.js';
72
+ import { describe_fact_serving_cross_tests } from './fact_serving.js';
73
+ import { describe_identity_parity_cross_tests } from './identity_parity.js';
74
+ import { describe_origin_cross_tests } from './origin.js';
75
+ import { describe_origin_conformance_cross_tests } from './origin_conformance.js';
76
+ import { describe_origin_scope_cross_tests } from './origin_scope.js';
77
+ import { describe_peer_ping_ws_tests } from './peer_ping_ws.js';
78
+ import { describe_query_shape_cross_tests } from './query_shape.js';
79
+ import { describe_ready_cross_tests } from './ready.js';
80
+ import { describe_role_grant_offer_enumeration_cross_tests, OFFER_GRANTOR_USERNAME } from './role_grant_offer_enumeration.js';
81
+ import { describe_role_grant_offer_lifecycle_cross_tests } from './role_grant_offer_lifecycle.js';
82
+ import { describe_role_grant_offer_notification_ws_tests } from './role_grant_offer_notification_ws.js';
83
+ import { describe_role_grant_participation_cross_tests } from './role_grant_participation.js';
84
+ import { describe_role_grant_role_grammar_cross_tests } from './role_grant_role_grammar.js';
85
+ import { describe_rpc_adversarial_cross_tests } from './rpc_adversarial.js';
86
+ import { describe_session_cap_cross_tests } from './session_cap.js';
87
+ import { describe_session_cookie_codec_cross_tests } from './session_cookie_codec.js';
88
+ import { default_cross_process_setup } from './setup.js';
89
+ import { describe_simple_request_cross_tests } from './simple_request.js';
90
+ import { SPINE_PARTICIPANT_ROLE, SPINE_ROLE_GATED_WS_PATH, SPINE_ROLE_GATED_WS_ROLES } from './spine_surface_constants.js';
91
+ import { describe_cross_process_sse_tests } from './sse_round_trip.js';
92
+ import { describe_standard_cross_process_tests } from './standard.js';
93
+ import { describe_testing_backdoor_cross_tests } from './testing_backdoor.js';
94
+ import { describe_token_lifetime_cross_tests } from './token_lifetime.js';
95
+ import { describe_token_scope_surface_cross_tests } from './token_scope_surface.js';
96
+ import { describe_transport_composition_cross_tests } from './transport_composition.js';
97
+ import { describe_ws_connection_cap_cross_tests } from './ws_connection_cap.js';
98
+ import { describe_ws_inbound_dispatch_cross_tests } from './ws_inbound_dispatch.js';
99
+ import { describe_ws_outbound_overflow_cross_tests } from './ws_outbound_overflow.js';
100
+ import { describe_ws_role_gated_cross_tests } from './ws_role_gated.js';
101
+ import { describe_cross_process_ws_tests } from './ws_round_trip.js';
102
+ /**
103
+ * Every shipped suite `describe_spine_cross_suites` runs, each named by its
104
+ * module under `testing/cross_backend/` (`ws_round_trip` is
105
+ * `describe_cross_process_ws_tests`, `standard` the standard bundle). Closed: a
106
+ * guard test holds it, with `STANDALONE_CROSS_SUITES`, to every module that
107
+ * exports a `describe_*` suite, so a new suite fails until it is registered.
108
+ */
109
+ export const SUITE_NAMES = [
110
+ 'account_lifecycle',
111
+ 'actor_lookup',
112
+ 'app_settings',
113
+ 'body_size',
114
+ 'body_size_smuggling',
115
+ 'cell_crud',
116
+ 'cell_gated_create',
117
+ 'cell_grant_role',
118
+ 'cell_moderate',
119
+ 'cell_ref_admission',
120
+ 'cell_relations',
121
+ 'cookie_attributes',
122
+ 'credential_deadline',
123
+ 'credential_header_robustness',
124
+ 'fact_serving',
125
+ 'identity_parity',
126
+ 'origin',
127
+ 'origin_conformance',
128
+ 'origin_scope',
129
+ 'peer_ping_ws',
130
+ 'query_shape',
131
+ 'ready',
132
+ 'role_grant_offer_enumeration',
133
+ 'role_grant_offer_lifecycle',
134
+ 'role_grant_offer_notification_ws',
135
+ 'role_grant_participation',
136
+ 'role_grant_role_grammar',
137
+ 'rpc_adversarial',
138
+ 'session_cap',
139
+ 'session_cookie_codec',
140
+ 'simple_request',
141
+ 'sse_round_trip',
142
+ 'standard',
143
+ 'testing_backdoor',
144
+ 'token_lifetime',
145
+ 'token_scope_surface',
146
+ 'transport_composition',
147
+ 'ws_connection_cap',
148
+ 'ws_inbound_dispatch',
149
+ 'ws_outbound_overflow',
150
+ 'ws_role_gated',
151
+ 'ws_round_trip'
152
+ ];
153
+ /**
154
+ * The shipped suite modules `describe_spine_cross_suites` leaves out, each with
155
+ * why. Their entry points stay as they are; a consumer calls them beside the
156
+ * one call.
157
+ */
158
+ export const STANDALONE_CROSS_SUITES = {
159
+ differential: 'compares two backends: it needs both handles of a dual-spawn project, not one backend',
160
+ login_security: 'needs a backend spawned with the login limiters enabled, which the standard suites would exhaust',
161
+ ws_action_rate_limit: 'needs a backend spawned with the action limiters enabled, which the standard suites would exhaust',
162
+ conformance_table: "a runner over the consumer's own cases, not a suite"
163
+ };
164
+ /**
165
+ * The suite options a handle's `config` supplies — the fields most cross
166
+ * suites take beside `setup_test`. For a suite called on its own:
167
+ * `describe_ready_cross_tests({setup_test, ...to_cross_suite_options(handle)})`
168
+ * passes extra fields the suite's type doesn't list, so destructure what it
169
+ * takes instead when calling it with an object literal.
170
+ */
171
+ export const to_cross_suite_options = (handle) => {
172
+ const { capabilities, base_url, rpc_path, ws_path, sse_path, cookie_name } = handle.config;
173
+ return { capabilities, base_url, rpc_path, ws_path, sse_path, cookie_name };
174
+ };
175
+ /** The capability-gated RPC-path shape the cell suites and several others share. */
176
+ const rpc_gated = (c, seed) => ({
177
+ setup_test: c.setup(seed),
178
+ capabilities: c.config.capabilities,
179
+ rpc_path: c.config.rpc_path
180
+ });
181
+ const SUITE_ENTRIES = {
182
+ account_lifecycle: {
183
+ derive: (c) => rpc_gated(c),
184
+ describe: describe_account_lifecycle_cross_tests,
185
+ required: { setup_test: true, capabilities: true }
186
+ },
187
+ actor_lookup: {
188
+ derive: (c) => ({ setup_test: c.setup(), rpc_path: c.config.rpc_path }),
189
+ describe: describe_actor_lookup_cross_tests,
190
+ required: { setup_test: true }
191
+ },
192
+ app_settings: {
193
+ derive: (c) => ({ setup_test: c.setup(), rpc_path: c.config.rpc_path }),
194
+ describe: describe_app_settings_cross_tests,
195
+ required: { setup_test: true }
196
+ },
197
+ body_size: {
198
+ derive: (c) => ({
199
+ setup_test: c.setup(),
200
+ rpc_path: c.config.rpc_path,
201
+ base_url: c.config.base_url,
202
+ rpc_max_body_bytes: c.options.rpc_max_body_bytes
203
+ }),
204
+ describe: describe_body_size_cross_tests,
205
+ required: { setup_test: true, base_url: true }
206
+ },
207
+ body_size_smuggling: {
208
+ derive: (c) => ({
209
+ base_url: c.config.base_url,
210
+ rpc_path: c.config.rpc_path,
211
+ rpc_max_body_bytes: c.options.rpc_max_body_bytes
212
+ }),
213
+ describe: describe_body_size_smuggling_cross_tests,
214
+ required: { base_url: true }
215
+ },
216
+ cell_crud: {
217
+ derive: (c) => rpc_gated(c),
218
+ describe: describe_cell_crud_cross_tests,
219
+ required: { setup_test: true, capabilities: true }
220
+ },
221
+ cell_gated_create: {
222
+ derive: (c) => rpc_gated(c),
223
+ describe: describe_cell_gated_create_cross_tests,
224
+ required: { setup_test: true, capabilities: true }
225
+ },
226
+ cell_grant_role: {
227
+ // the holder is seeded at reset: `CELL_EDITOR_ROLE` has no grant path
228
+ derive: (c) => {
229
+ const role = c.options.suite_roles?.cell_grant ?? CELL_EDITOR_ROLE;
230
+ return {
231
+ ...rpc_gated(c, {
232
+ extra_accounts: [{ username: CELL_ROLE_HOLDER_USERNAME, roles: [role] }]
233
+ }),
234
+ role
235
+ };
236
+ },
237
+ describe: describe_cell_grant_role_cross_tests,
238
+ required: { setup_test: true, capabilities: true }
239
+ },
240
+ cell_moderate: {
241
+ derive: (c) => rpc_gated(c),
242
+ describe: describe_cell_moderate_cross_tests,
243
+ required: { setup_test: true, capabilities: true }
244
+ },
245
+ cell_ref_admission: {
246
+ derive: (c) => rpc_gated(c),
247
+ describe: describe_cell_ref_admission_cross_tests,
248
+ required: { setup_test: true, capabilities: true }
249
+ },
250
+ cell_relations: {
251
+ derive: (c) => rpc_gated(c),
252
+ describe: describe_cell_relations_cross_tests,
253
+ required: { setup_test: true, capabilities: true }
254
+ },
255
+ cookie_attributes: {
256
+ derive: (c) => ({ setup_test: c.setup(), cookie_name: c.config.cookie_name }),
257
+ describe: describe_cookie_attributes_cross_tests,
258
+ required: { setup_test: true, cookie_name: true }
259
+ },
260
+ credential_deadline: {
261
+ derive: (c) => ({
262
+ setup_test: c.setup(),
263
+ capabilities: c.config.capabilities,
264
+ base_url: c.config.base_url,
265
+ ws_path: c.config.ws_path,
266
+ sse_path: c.config.sse_path,
267
+ rpc_path: c.config.rpc_path,
268
+ ws_account_roles: c.options.ws_required_roles
269
+ }),
270
+ describe: describe_credential_deadline_cross_tests,
271
+ required: { setup_test: true, capabilities: true, base_url: true, ws_path: true }
272
+ },
273
+ credential_header_robustness: {
274
+ derive: (c) => ({
275
+ base_url: c.config.base_url,
276
+ rpc_path: c.config.rpc_path,
277
+ daemon_token: c.handle.daemon_token
278
+ }),
279
+ describe: describe_credential_header_robustness_cross_tests,
280
+ required: { base_url: true, daemon_token: true }
281
+ },
282
+ fact_serving: {
283
+ // the multi-actor setup reaches the fallthrough a single-actor keeper can't
284
+ derive: (c) => ({
285
+ ...rpc_gated(c),
286
+ setup_test_multi_actor: c.setup({ extra_actors: ['second_persona'] })
287
+ }),
288
+ describe: describe_fact_serving_cross_tests,
289
+ required: { setup_test: true, capabilities: true }
290
+ },
291
+ identity_parity: {
292
+ derive: (c) => ({ setup_test: c.setup() }),
293
+ describe: describe_identity_parity_cross_tests,
294
+ required: { setup_test: true }
295
+ },
296
+ origin: {
297
+ derive: (c) => ({ setup_test: c.setup(), rpc_path: c.config.rpc_path }),
298
+ describe: describe_origin_cross_tests,
299
+ required: { setup_test: true }
300
+ },
301
+ origin_conformance: {
302
+ derive: (c) => ({ setup_test: c.setup(), rpc_path: c.config.rpc_path }),
303
+ describe: describe_origin_conformance_cross_tests,
304
+ required: { setup_test: true }
305
+ },
306
+ origin_scope: {
307
+ derive: (c) => ({
308
+ setup_test: c.setup(),
309
+ capabilities: c.config.capabilities,
310
+ base_url: c.config.base_url
311
+ }),
312
+ describe: describe_origin_scope_cross_tests,
313
+ required: { setup_test: true, capabilities: true }
314
+ },
315
+ peer_ping_ws: {
316
+ derive: (c) => ({
317
+ setup_test: c.setup(),
318
+ capabilities: c.config.capabilities,
319
+ base_url: c.config.base_url,
320
+ ws_path: c.config.ws_path
321
+ }),
322
+ describe: describe_peer_ping_ws_tests,
323
+ required: { setup_test: true, capabilities: true, base_url: true, ws_path: true }
324
+ },
325
+ query_shape: {
326
+ derive: (c) => rpc_gated(c),
327
+ describe: describe_query_shape_cross_tests,
328
+ required: { setup_test: true, capabilities: true }
329
+ },
330
+ ready: {
331
+ derive: (c) => ({ setup_test: c.setup(), capabilities: c.config.capabilities }),
332
+ describe: describe_ready_cross_tests,
333
+ required: { setup_test: true, capabilities: true }
334
+ },
335
+ role_grant_offer_enumeration: {
336
+ // a sibling actor for the wrong-persona arm, and a single-actor admin
337
+ // grantor (the keeper can't offer to itself)
338
+ derive: (c) => ({
339
+ setup_test: c.setup({
340
+ extra_actors: ['offer_sibling'],
341
+ extra_accounts: [{ username: OFFER_GRANTOR_USERNAME, roles: [ROLE_ADMIN] }]
342
+ }),
343
+ rpc_path: c.config.rpc_path
344
+ }),
345
+ describe: describe_role_grant_offer_enumeration_cross_tests,
346
+ required: { setup_test: true }
347
+ },
348
+ role_grant_offer_lifecycle: {
349
+ derive: (c) => ({
350
+ setup_test: c.setup(),
351
+ rpc_path: c.config.rpc_path,
352
+ role: c.options.suite_roles?.conferral
353
+ }),
354
+ describe: describe_role_grant_offer_lifecycle_cross_tests,
355
+ required: { setup_test: true }
356
+ },
357
+ role_grant_offer_notification_ws: {
358
+ derive: (c) => ({
359
+ setup_test: c.setup(),
360
+ capabilities: c.config.capabilities,
361
+ base_url: c.config.base_url,
362
+ ws_path: c.config.ws_path,
363
+ ws_required_roles: c.options.ws_required_roles
364
+ }),
365
+ describe: describe_role_grant_offer_notification_ws_tests,
366
+ required: { setup_test: true, capabilities: true, base_url: true, ws_path: true }
367
+ },
368
+ role_grant_participation: {
369
+ derive: (c) => ({
370
+ setup_test: c.setup(),
371
+ rpc_path: c.config.rpc_path,
372
+ role: c.options.suite_roles?.conferral
373
+ }),
374
+ describe: describe_role_grant_participation_cross_tests,
375
+ required: { setup_test: true }
376
+ },
377
+ role_grant_role_grammar: {
378
+ derive: (c) => ({ setup_test: c.setup(), rpc_path: c.config.rpc_path }),
379
+ describe: describe_role_grant_role_grammar_cross_tests,
380
+ required: { setup_test: true }
381
+ },
382
+ rpc_adversarial: {
383
+ derive: (c) => ({
384
+ setup_test: c.setup(),
385
+ surface_source: c.options.surface_source,
386
+ live_rpc_endpoints: c.options.live_rpc_endpoints &&
387
+ resolve_rpc_endpoints_for_setup(c.options.live_rpc_endpoints, c.options.session_options),
388
+ rpc_path: c.config.rpc_path
389
+ }),
390
+ describe: describe_rpc_adversarial_cross_tests,
391
+ required: { setup_test: true, surface_source: true }
392
+ },
393
+ session_cap: {
394
+ derive: (c) => ({
395
+ setup_test: c.setup(),
396
+ ws: c.ws,
397
+ ws_account_roles: c.options.ws_required_roles
398
+ }),
399
+ describe: describe_session_cap_cross_tests,
400
+ required: { setup_test: true }
401
+ },
402
+ session_cookie_codec: {
403
+ derive: (c) => ({
404
+ setup_test: c.setup(),
405
+ cookie_name: c.config.cookie_name,
406
+ cookie_keys: c.handle.config.env.SECRET_FUZ_COOKIE_KEYS ?? '',
407
+ rpc_path: c.config.rpc_path
408
+ }),
409
+ describe: describe_session_cookie_codec_cross_tests,
410
+ required: { setup_test: true, cookie_name: true, cookie_keys: true }
411
+ },
412
+ simple_request: {
413
+ derive: (c) => ({ setup_test: c.setup(), rpc_path: c.config.rpc_path }),
414
+ describe: describe_simple_request_cross_tests,
415
+ required: { setup_test: true }
416
+ },
417
+ sse_round_trip: {
418
+ derive: (c) => ({
419
+ setup_test: c.setup(),
420
+ capabilities: c.config.capabilities,
421
+ base_url: c.config.base_url,
422
+ sse_path: c.config.sse_path,
423
+ rpc_path: c.config.rpc_path
424
+ }),
425
+ describe: describe_cross_process_sse_tests,
426
+ required: { setup_test: true, capabilities: true, base_url: true }
427
+ },
428
+ standard: {
429
+ // a keeper-only account for the admin suite's keeper ≠ admin probe —
430
+ // `ROLE_KEEPER` is bootstrap-only, so it is seeded at reset
431
+ derive: (c) => ({
432
+ setup_test: c.setup({
433
+ extra_accounts: [{ username: 'non_admin_keeper', roles: [ROLE_KEEPER] }]
434
+ }),
435
+ surface_source: c.options.surface_source,
436
+ capabilities: c.config.capabilities,
437
+ session_options: c.options.session_options,
438
+ rpc_endpoints: c.options.rpc_endpoints,
439
+ roles: c.options.roles,
440
+ rpc_success_fixtures: c.options.rpc_success_fixtures,
441
+ rpc_skip_methods: c.options.rpc_skip_methods,
442
+ rpc_input_overrides: c.options.rpc_input_overrides
443
+ }),
444
+ describe: describe_standard_cross_process_tests,
445
+ required: {
446
+ setup_test: true,
447
+ surface_source: true,
448
+ session_options: true,
449
+ rpc_endpoints: true,
450
+ capabilities: true
451
+ }
452
+ },
453
+ testing_backdoor: {
454
+ derive: (c) => ({ setup_test: c.setup(), rpc_path: c.config.rpc_path, ws: c.ws }),
455
+ describe: describe_testing_backdoor_cross_tests,
456
+ required: { setup_test: true }
457
+ },
458
+ token_lifetime: {
459
+ derive: (c) => ({ setup_test: c.setup(), rpc_path: c.config.rpc_path }),
460
+ describe: describe_token_lifetime_cross_tests,
461
+ required: { setup_test: true }
462
+ },
463
+ token_scope_surface: {
464
+ derive: (c) => ({ ...rpc_gated(c), sse_path: c.config.sse_path }),
465
+ describe: describe_token_scope_surface_cross_tests,
466
+ required: { setup_test: true, capabilities: true }
467
+ },
468
+ transport_composition: {
469
+ derive: (c) => ({
470
+ ...rpc_gated(c),
471
+ base_url: c.config.base_url,
472
+ ws_path: c.config.ws_path,
473
+ sse_path: c.config.sse_path,
474
+ multi_actor: { setup_test: c.setup({ extra_actors: ['keeper_second_persona'] }) },
475
+ rpc_max_body_bytes: c.options.rpc_max_body_bytes
476
+ }),
477
+ describe: describe_transport_composition_cross_tests,
478
+ required: { setup_test: true, capabilities: true, base_url: true }
479
+ },
480
+ ws_connection_cap: {
481
+ derive: (c) => ({
482
+ setup_test: c.setup(),
483
+ capabilities: c.config.capabilities,
484
+ base_url: c.config.base_url,
485
+ ws_path: c.config.ws_path
486
+ }),
487
+ describe: describe_ws_connection_cap_cross_tests,
488
+ required: { setup_test: true, capabilities: true, base_url: true, ws_path: true }
489
+ },
490
+ ws_inbound_dispatch: {
491
+ derive: (c) => ({
492
+ setup_test: c.setup(),
493
+ capabilities: c.config.capabilities,
494
+ base_url: c.config.base_url,
495
+ ws_path: c.config.ws_path
496
+ }),
497
+ describe: describe_ws_inbound_dispatch_cross_tests,
498
+ required: { setup_test: true, capabilities: true, base_url: true, ws_path: true }
499
+ },
500
+ ws_outbound_overflow: {
501
+ derive: (c) => ({
502
+ setup_test: c.setup(),
503
+ capabilities: c.config.capabilities,
504
+ base_url: c.config.base_url,
505
+ ws_path: c.config.ws_path,
506
+ rpc_path: c.config.rpc_path
507
+ }),
508
+ describe: describe_ws_outbound_overflow_cross_tests,
509
+ required: { setup_test: true, capabilities: true, base_url: true, ws_path: true }
510
+ },
511
+ ws_role_gated: {
512
+ // the reference spines' role-gated endpoint; a backend mounting its own
513
+ // overrides these, and one without it states `ws_role_gated: false`
514
+ derive: (c) => ({
515
+ setup_test: c.setup(),
516
+ capabilities: c.config.capabilities,
517
+ base_url: c.config.base_url,
518
+ ws_path: c.config.ws_path,
519
+ gated_ws_path: SPINE_ROLE_GATED_WS_PATH,
520
+ gated_roles: SPINE_ROLE_GATED_WS_ROLES,
521
+ scoped_role: SPINE_PARTICIPANT_ROLE
522
+ }),
523
+ describe: describe_ws_role_gated_cross_tests,
524
+ required: {
525
+ setup_test: true,
526
+ capabilities: true,
527
+ base_url: true,
528
+ ws_path: true,
529
+ gated_ws_path: true,
530
+ gated_roles: true,
531
+ scoped_role: true
532
+ }
533
+ },
534
+ ws_round_trip: {
535
+ derive: (c) => ({
536
+ setup_test: c.setup(),
537
+ capabilities: c.config.capabilities,
538
+ base_url: c.config.base_url,
539
+ ws_path: c.config.ws_path,
540
+ rpc_path: c.config.rpc_path,
541
+ ws_account_roles: c.options.ws_required_roles,
542
+ max_message_bytes: c.options.ws_max_message_bytes
543
+ }),
544
+ describe: describe_cross_process_ws_tests,
545
+ required: { setup_test: true, capabilities: true, base_url: true, ws_path: true }
546
+ }
547
+ };
548
+ /** Concatenate a suite's seeding onto the base setup options. */
549
+ const merge_setup_options = (base, seed) => ({
550
+ ...base,
551
+ ...seed,
552
+ extra_keeper_roles: [...(base?.extra_keeper_roles ?? []), ...(seed?.extra_keeper_roles ?? [])],
553
+ extra_accounts: [...(base?.extra_accounts ?? []), ...(seed?.extra_accounts ?? [])],
554
+ extra_actors: [...(base?.extra_actors ?? []), ...(seed?.extra_actors ?? [])]
555
+ });
556
+ const is_suite_name = (name) => SUITE_NAMES.includes(name);
557
+ /**
558
+ * Refuse an exclude with an empty reason, an unknown suite name, and a suite
559
+ * both excluded and overridden — before anything is registered.
560
+ */
561
+ const validate_spine_cross_suites_options = (options) => {
562
+ for (const [name, reason] of Object.entries(options.exclude ?? {})) {
563
+ if (!is_suite_name(name)) {
564
+ throw new Error(`describe_spine_cross_suites: exclude names unknown suite '${name}'`);
565
+ }
566
+ if (typeof reason !== 'string' || reason.trim() === '') {
567
+ throw new Error(`describe_spine_cross_suites: exclude '${name}' needs a reason`);
568
+ }
569
+ if (options.overrides?.[name] !== undefined) {
570
+ throw new Error(`describe_spine_cross_suites: '${name}' is both excluded and overridden`);
571
+ }
572
+ }
573
+ for (const name of Object.keys(options.overrides ?? {})) {
574
+ if (!is_suite_name(name)) {
575
+ throw new Error(`describe_spine_cross_suites: overrides names unknown suite '${name}'`);
576
+ }
577
+ }
578
+ };
579
+ const run_suite = (name, context) => {
580
+ const entry = SUITE_ENTRIES[name];
581
+ const derived = entry.derive(context);
582
+ const override = context.options.overrides?.[name];
583
+ const patch = typeof override === 'function' ? override(derived) : override;
584
+ const suite_options = { ...derived, ...patch };
585
+ for (const field of Object.keys(entry.required)) {
586
+ const value = suite_options[field];
587
+ if (value === undefined || value === '') {
588
+ throw new Error(`describe_spine_cross_suites: '${name}' needs \`${field}\`, which neither the handle ` +
589
+ `nor the override gives — pass \`overrides.${name}\` with it or exclude '${name}' with a reason`);
590
+ }
591
+ }
592
+ entry.describe(suite_options);
593
+ };
594
+ /**
595
+ * Run every shipped single-backend cross suite against one spawned backend —
596
+ * see the module doc for what the options add and what stays outside.
597
+ *
598
+ * @param handle - the backend, as `inject_backend_handle()` returns it
599
+ * @param options - the declared surface, plus excludes and overrides
600
+ * @throws Error - on an exclude with no reason, an unknown suite name, a suite
601
+ * both excluded and overridden, or a suite missing an input the handle
602
+ * doesn't carry
603
+ */
604
+ export const describe_spine_cross_suites = (handle, options) => {
605
+ validate_spine_cross_suites_options(options);
606
+ const config = to_cross_suite_options(handle);
607
+ const context = {
608
+ handle,
609
+ config,
610
+ options,
611
+ setup: (seed) => default_cross_process_setup(handle, merge_setup_options(options.setup, seed)),
612
+ ws: config.capabilities.ws ? { base_url: config.base_url, ws_path: config.ws_path } : undefined
613
+ };
614
+ const excluded = Object.entries(options.exclude ?? {});
615
+ for (const name of SUITE_NAMES) {
616
+ if (options.exclude?.[name] !== undefined)
617
+ continue;
618
+ run_suite(name, context);
619
+ }
620
+ if (excluded.length > 0) {
621
+ describe('spine cross suites excluded on this backend', () => {
622
+ for (const [name, reason] of excluded)
623
+ test.skip(`${name}: ${reason}`, () => { });
624
+ });
625
+ }
626
+ };
@@ -15,6 +15,26 @@ export declare const TESTING_ACTION_AUTH: {
15
15
  };
16
16
  /** RPC endpoint mount path — matches the binary's `/api/rpc`. */
17
17
  export declare const SPINE_RPC_PATH = "/api/rpc";
18
+ /** Ungated WebSocket endpoint mount path — matches the binaries' `/api/ws`. */
19
+ export declare const SPINE_WS_PATH = "/api/ws";
20
+ /**
21
+ * Mount prefix of the account REST routes (login, logout, password, status,
22
+ * signup, bootstrap) on both spine binaries. The `SPINE_ACCOUNT_*_PATH`
23
+ * constants below are the routes under it the suites drive.
24
+ */
25
+ export declare const SPINE_ACCOUNT_PATH_PREFIX = "/api/account";
26
+ /** REST login route. */
27
+ export declare const SPINE_ACCOUNT_LOGIN_PATH = "/api/account/login";
28
+ /** REST logout route. */
29
+ export declare const SPINE_ACCOUNT_LOGOUT_PATH = "/api/account/logout";
30
+ /** REST password-change route. */
31
+ export declare const SPINE_ACCOUNT_PASSWORD_PATH = "/api/account/password";
32
+ /** REST account-status route. */
33
+ export declare const SPINE_ACCOUNT_STATUS_PATH = "/api/account/status";
34
+ /** REST signup route. */
35
+ export declare const SPINE_ACCOUNT_SIGNUP_PATH = "/api/account/signup";
36
+ /** REST bootstrap route — the default `BackendConfig.bootstrap_path`. */
37
+ export declare const SPINE_ACCOUNT_BOOTSTRAP_PATH = "/api/account/bootstrap";
18
38
  /**
19
39
  * Audit-log SSE stream path — `/api/admin` prefix + the
20
40
  * `create_audit_log_route_specs` `/audit/stream` route. Matches the default
@@ -23,6 +43,15 @@ export declare const SPINE_RPC_PATH = "/api/rpc";
23
43
  * surface stub leaves `ctx.audit_sse` null so the snapshot stays SSE-free.
24
44
  */
25
45
  export declare const SPINE_SSE_PATH = "/api/admin/audit/stream";
46
+ /**
47
+ * The request-body cap both spines ship by default, 1 MiB
48
+ * (`DEFAULT_MAX_BODY_SIZE` in TS, `DEFAULT_BODY_LIMIT_BYTES` in `fuz_http`).
49
+ * Kept here as the cross-impl contract value rather than imported from either
50
+ * impl — the boundary the body-size suites pin is the shared default, and a
51
+ * change to either is a deliberate cross-impl decision that would revisit them
52
+ * regardless.
53
+ */
54
+ export declare const SPINE_BODY_LIMIT_DEFAULT_BYTES: number;
26
55
  /**
27
56
  * App role the role-shaped-`cell_grant` cross suite exercises. Registered
28
57
  * 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,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"}