@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
@@ -0,0 +1,148 @@
1
+ import '../assert_dev_env.js';
2
+ /**
3
+ * Cargo-built test binaries for cross-backend projects — build before the
4
+ * spawn, then spawn the binary itself.
5
+ *
6
+ * A config that spawns `cargo run` builds inside `spawn_backend`'s health
7
+ * window, so a cold build can outlast the startup timeout, and the build's
8
+ * output is held in the spawn's stderr tail rather than shown.
9
+ * `prepare_cargo_binary` runs the build first, with its output inherited, as a
10
+ * pre-spawn hook (`create_cross_backend_global_setup`'s `before_spawn`), and
11
+ * the config's `start_command` names the built binary
12
+ * (`resolve_cargo_binary_path`), so the spawn starts at once.
13
+ *
14
+ * The binary's path comes from `cargo metadata`: under the workspace's
15
+ * resolved `target_directory`, so `CARGO_TARGET_DIR` and `build.target-dir`
16
+ * are honoured, in the profile's output directory.
17
+ *
18
+ * @module
19
+ */
20
+ import { execFileSync } from 'node:child_process';
21
+ import { existsSync } from 'node:fs';
22
+ import { join } from 'node:path';
23
+ /**
24
+ * Env var skipping the build, for iteration on a known-current binary: `1` or
25
+ * `true` skips it, any other value (`0`, `false`, empty) builds.
26
+ */
27
+ export const NO_REBUILD_ENV = 'FUZ_TESTING_NO_REBUILD';
28
+ /**
29
+ * Whether an `NO_REBUILD_ENV` value asks to skip the build — only an explicit
30
+ * `1` / `true`, so `FUZ_TESTING_NO_REBUILD=0` still builds.
31
+ *
32
+ * @param value - the variable's value, `undefined` when unset
33
+ */
34
+ export const is_no_rebuild_requested = (value) => value === '1' || value?.toLowerCase() === 'true';
35
+ /**
36
+ * The directory under the target directory a profile's output lands in —
37
+ * `debug` for `dev`, the profile's own name otherwise (`release`, a custom
38
+ * `cross-test`).
39
+ *
40
+ * @param profile - the Cargo profile
41
+ */
42
+ export const to_cargo_profile_dir = (profile) => profile === 'dev' ? 'debug' : profile;
43
+ /**
44
+ * The binary path `cargo build --profile <profile> --bin <bin>` writes, from
45
+ * `cargo metadata --no-deps --format-version 1` output.
46
+ *
47
+ * @param metadata_json - the `cargo metadata` output
48
+ * @param bin - the binary's name
49
+ * @param profile - the Cargo profile
50
+ * @returns the binary's absolute path
51
+ * @throws Error when the output carries no `target_directory`
52
+ */
53
+ export const to_cargo_binary_path = (metadata_json, bin, profile) => {
54
+ const metadata = JSON.parse(metadata_json);
55
+ if (typeof metadata.target_directory !== 'string' || !metadata.target_directory) {
56
+ throw new Error('`cargo metadata` output has no `target_directory`');
57
+ }
58
+ return join(metadata.target_directory, to_cargo_profile_dir(profile), bin);
59
+ };
60
+ /**
61
+ * Per-process memo of each workspace's target directory metadata. On
62
+ * `globalThis` rather than in module scope, so every project's `globalSetup` in
63
+ * one vitest process shares it whether or not they share this module's
64
+ * instance.
65
+ */
66
+ const CARGO_METADATA_MEMO_KEY = '__fuz_app_cargo_metadata_memo';
67
+ const get_metadata_memo = () => {
68
+ const holder = globalThis;
69
+ return (holder[CARGO_METADATA_MEMO_KEY] ??= new Map());
70
+ };
71
+ /**
72
+ * How long `cargo metadata` may take (ms). Usually well under a second, but
73
+ * the first run in a checkout can have rustup install the pinned toolchain.
74
+ */
75
+ const CARGO_METADATA_TIMEOUT_MS = 120_000;
76
+ /**
77
+ * Throw naming the workspace when its directory is missing — a spawn with a
78
+ * missing `cwd` otherwise fails as `spawnSync cargo ENOENT`, which reads as
79
+ * cargo not being installed.
80
+ */
81
+ const assert_workspace_dir = (workspace_dir) => {
82
+ if (!existsSync(workspace_dir)) {
83
+ throw new Error(`the Cargo workspace ${workspace_dir} does not exist`);
84
+ }
85
+ };
86
+ const read_cargo_metadata = (workspace_dir) => {
87
+ const memo = get_metadata_memo();
88
+ let metadata_json = memo.get(workspace_dir);
89
+ if (metadata_json === undefined) {
90
+ assert_workspace_dir(workspace_dir);
91
+ try {
92
+ metadata_json = execFileSync('cargo', ['metadata', '--no-deps', '--format-version', '1'], {
93
+ cwd: workspace_dir,
94
+ encoding: 'utf-8',
95
+ stdio: ['ignore', 'pipe', 'inherit'],
96
+ maxBuffer: 64 * 1024 * 1024,
97
+ timeout: CARGO_METADATA_TIMEOUT_MS
98
+ });
99
+ }
100
+ catch (error) {
101
+ const code = error.code;
102
+ throw new Error(code === 'ETIMEDOUT'
103
+ ? `\`cargo metadata\` in ${workspace_dir} took over ${CARGO_METADATA_TIMEOUT_MS}ms`
104
+ : `\`cargo metadata\` in ${workspace_dir} failed: ${error.message}`, { cause: error });
105
+ }
106
+ memo.set(workspace_dir, metadata_json);
107
+ }
108
+ return metadata_json;
109
+ };
110
+ /**
111
+ * The path of a Cargo-built binary, without building it — what a config's
112
+ * `start_command` names. Runs `cargo metadata` once per process per workspace,
113
+ * so it needs cargo on PATH.
114
+ *
115
+ * @param options - the workspace, package, binary and profile
116
+ * @returns the binary's absolute path
117
+ * @throws Error when the workspace is missing or `cargo metadata` fails
118
+ */
119
+ export const resolve_cargo_binary_path = (options) => {
120
+ const { workspace_dir, package: pkg, bin = pkg, profile = 'dev' } = options;
121
+ return to_cargo_binary_path(read_cargo_metadata(workspace_dir), bin, profile);
122
+ };
123
+ /**
124
+ * Build a Cargo binary before its backend spawns, unless `NO_REBUILD_ENV`
125
+ * asks to skip it, and return its path. The build's output is inherited, so a
126
+ * cold build shows its progress, and a failed build throws — the project fails
127
+ * loudly rather than spawning a stale binary. `cargo build` is incremental, so
128
+ * a build with nothing changed is quick.
129
+ *
130
+ * Synchronous: vitest awaits each project's `globalSetup` in turn, so one
131
+ * invocation selecting several projects builds once, then finds the build
132
+ * current.
133
+ *
134
+ * @param options - the workspace, package, binary and profile
135
+ * @returns the binary's absolute path (`resolve_cargo_binary_path`)
136
+ * @throws Error when the workspace is missing, the build fails, or `cargo metadata` fails
137
+ */
138
+ export const prepare_cargo_binary = (options) => {
139
+ const { workspace_dir, package: pkg, bin = pkg, profile = 'dev' } = options;
140
+ if (!is_no_rebuild_requested(process.env[NO_REBUILD_ENV])) {
141
+ assert_workspace_dir(workspace_dir);
142
+ execFileSync('cargo', ['build', '-p', pkg, '--bin', bin, '--profile', profile], {
143
+ cwd: workspace_dir,
144
+ stdio: 'inherit'
145
+ });
146
+ }
147
+ return resolve_cargo_binary_path(options);
148
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"cell_crud.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/cell_crud.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AA6D9B,OAAO,KAAK,EAAE,uCAAuC,EAAE,MAAM,YAAY,CAAC;AAG1E,eAAO,MAAM,8BAA8B,GAC1C,SAAS,uCAAuC,KAC9C,IAggBF,CAAC"}
1
+ {"version":3,"file":"cell_crud.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/cell_crud.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AA0E9B,OAAO,KAAK,EAAE,uCAAuC,EAAE,MAAM,YAAY,CAAC;AAgE1E,eAAO,MAAM,8BAA8B,GAC1C,SAAS,uCAAuC,KAC9C,IA4uBF,CAAC"}
@@ -23,6 +23,9 @@ import '../assert_dev_env.js';
23
23
  * - a non-owner non-admin editing / reading / deleting another's private cell
24
24
  * gets 404 (IDOR mask), never 403;
25
25
  * - admin reaches any cell;
26
+ * - `cell_list` pages honor `limit` + `offset`, and a page is visible rows:
27
+ * a newer run of cells the caller can't see never crowds the visible ones
28
+ * out, for a non-owner and for anon, and an admin's pages tile every row;
26
29
  * - duplicate active `path` → 409 (`cell_path_taken`);
27
30
  * - `path` write by a non-admin → 403 (`cell_path_admin_only`), on both create
28
31
  * and update (even by the owner);
@@ -35,7 +38,13 @@ import '../assert_dev_env.js';
35
38
  * accepted as a list filter that matches nothing;
36
39
  * - a `kind` of exactly `CELL_KIND_LENGTH_MAX` UTF-16 code units is stored
37
40
  * whole, and one unit past it is `invalid_params` on create and as a list
38
- * filter.
41
+ * filter;
42
+ * - a `data` that is no `CellData` — not an object, or a `label` / `summary`
43
+ * that is no string — is 400 `invalid_params` with the generic message and
44
+ * no reason on `cell_create`, `cell_update` and (with
45
+ * `capabilities.cell_relations`) `cell_clone`'s `with_data_patch`, ahead of
46
+ * every cell check (a missing or hidden cell refuses it the same way, never
47
+ * with the 404 mask), and writes no cell.
39
48
  *
40
49
  * The visibility-manage-tier 403 (`cell_visibility_manage_only`) needs a
41
50
  * non-owner editor, which only a `cell_grant` can produce, so it lives in
@@ -45,11 +54,64 @@ import '../assert_dev_env.js';
45
54
  * @module
46
55
  */
47
56
  import { describe, assert } from 'vitest';
48
- import { CELL_KIND_LENGTH_MAX, CellCreateOutput, CellDeleteOutput, CellGetOutput, CellListOutput, CellUpdateOutput } from '../../auth/cell_action_specs.js';
57
+ import { jsonrpc_error_messages } from '../../http/jsonrpc_errors.js';
58
+ import { CELL_KIND_LENGTH_MAX, CELL_LIST_LIMIT_MAX, CellCreateOutput, CellDeleteOutput, CellGetOutput, CellListOutput, CellUpdateOutput } from '../../auth/cell_action_specs.js';
49
59
  import { test_if } from './capabilities.js';
50
- import { cross_rpc_call, error_reason, expect_output } from './cell_cross_helpers.js';
60
+ import { cross_rpc_call, error_reason, expect_output } from './cross_rpc.js';
51
61
  import { assert_iso8601_seconds, assert_iso8601_seconds_nullable } from './wire_shapes.js';
52
62
  import { SPINE_RPC_PATH } from './spine_surface_constants.js';
63
+ /**
64
+ * `data` values that are no `CellData` — not an object, or an object whose
65
+ * `label` / `summary` is no string. Twin of the Rust spine's mistyped-data
66
+ * table in its cell authz tests.
67
+ */
68
+ const MISTYPED_CELL_DATA = [
69
+ 'not_an_object',
70
+ 42,
71
+ true,
72
+ [1],
73
+ { label: 123 },
74
+ { label: null },
75
+ { summary: {} },
76
+ { summary: false }
77
+ ];
78
+ /** The message every schema refusal answers, naming no field. */
79
+ const INVALID_PARAMS_MESSAGE = jsonrpc_error_messages.invalid_params().message;
80
+ /**
81
+ * Assert `r` is a schema refusal: 400 `invalid_params` with the generic
82
+ * message and no `data`, save the Zod `issues` a TS spine adds under DEV
83
+ * alone — an array of issue objects, each with a string `code` and
84
+ * `message`, and never a `reason`.
85
+ */
86
+ const assert_schema_refusal = (r, label) => {
87
+ const detail = `${label}: got ${r.status} ${JSON.stringify(r.error ?? r.result)}`;
88
+ assert.strictEqual(r.status, 400, detail);
89
+ const { error } = r;
90
+ assert.ok(error, detail);
91
+ assert.strictEqual(error.code, -32602, detail);
92
+ assert.strictEqual(error.message, INVALID_PARAMS_MESSAGE, detail);
93
+ const { data } = error;
94
+ if (data === undefined)
95
+ return;
96
+ assert.ok(typeof data === 'object' && data !== null && Object.keys(data).join() === 'issues', `${detail} — data beyond the DEV-only issues`);
97
+ const { issues } = data;
98
+ assert.ok(Array.isArray(issues), `${detail} — DEV-only issues that are no array`);
99
+ for (const issue of issues) {
100
+ assert.ok(typeof issue === 'object' &&
101
+ issue !== null &&
102
+ typeof issue.code === 'string' &&
103
+ typeof issue.message === 'string', `${detail} — a DEV-only issue that is no Zod issue`);
104
+ }
105
+ };
106
+ /**
107
+ * Assert `r` is the IDOR mask: 404 with reason `cell_not_found` — the
108
+ * well-typed control beside a schema refusal of the same call.
109
+ */
110
+ const assert_cell_not_found = (r, label) => {
111
+ const detail = `${label}: got ${r.status} ${JSON.stringify(r.error ?? r.result)}`;
112
+ assert.strictEqual(r.status, 404, detail);
113
+ assert.strictEqual(error_reason(r), 'cell_not_found', detail);
114
+ };
53
115
  export const describe_cell_crud_cross_tests = (options) => {
54
116
  const { setup_test, capabilities } = options;
55
117
  const rpc_path = options.rpc_path ?? SPINE_RPC_PATH;
@@ -194,6 +256,59 @@ export const describe_cell_crud_cross_tests = (options) => {
194
256
  assert.ok(!update_path.ok, 'non-admin set a path on update');
195
257
  assert.strictEqual(error_reason(update_path), 'cell_path_admin_only');
196
258
  });
259
+ test_if(capabilities.cell_crud, 'cell_list pages: limit + offset honored; hidden rows never crowd visible ones out of a page', async () => {
260
+ const fixture = await setup_test();
261
+ const owner = await fixture.create_account({ username: 'cell_page_owner' });
262
+ const other = await fixture.create_account({ username: 'cell_page_other' });
263
+ const viewer = await fixture.create_account({ username: 'cell_page_viewer' });
264
+ const t = fixture.fresh_transport();
265
+ const kind = 'page_probe';
266
+ const create = async (headers, visibility) => expect_output(await cross_rpc_call(t, rpc_path, 'cell_create', { kind, data: {}, visibility }, headers), CellCreateOutput).cell.id;
267
+ const owner_h = owner.create_session_headers();
268
+ const other_h = other.create_session_headers();
269
+ // oldest first: the visible rows, then a newer run of hidden ones —
270
+ // two owners' private cells — longer than a page, so the newest
271
+ // `limit` rows are all hidden from the viewer
272
+ const visible = [];
273
+ for (let i = 0; i < 5; i++) {
274
+ visible.push(await create(i % 2 === 0 ? owner_h : other_h, 'public'));
275
+ }
276
+ const hidden = [];
277
+ for (let i = 0; i < 6; i++) {
278
+ hidden.push(await create(i % 2 === 0 ? owner_h : other_h, 'private'));
279
+ }
280
+ const limit = 3;
281
+ const page = async (transport, headers, params) => expect_output(await cross_rpc_call(transport, rpc_path, 'cell_list', { kind, ...params }, headers), CellListOutput).cells.map((c) => c.id);
282
+ // newest first (the default order), so the visible rows, newest first
283
+ const visible_desc = [...visible].reverse();
284
+ for (const [label, transport, headers] of [
285
+ ['a non-owner viewer', t, viewer.create_session_headers()],
286
+ ['anon', fixture.fresh_transport({ origin: null }), {}]
287
+ ]) {
288
+ const first = await page(transport, headers, { limit });
289
+ assert.deepStrictEqual(first, visible_desc.slice(0, limit), `${label}: the first page is the newest visible rows, full to limit`);
290
+ const second = await page(transport, headers, { limit, offset: limit });
291
+ assert.deepStrictEqual(second, visible_desc.slice(limit), `${label}: the next page is the rest of the visible rows`);
292
+ const past = await page(transport, headers, { limit, offset: visible.length });
293
+ assert.deepStrictEqual(past, [], `${label}: a page past the visible rows is empty`);
294
+ for (const id of [...first, ...second]) {
295
+ assert.ok(!hidden.includes(id), `${label}: a page leaked a hidden row`);
296
+ }
297
+ }
298
+ // an admin sees every row, paged the same way
299
+ const admin_h = fixture.create_session_headers();
300
+ const all_desc = [...visible, ...hidden].reverse();
301
+ const admin_pages = [];
302
+ for (let offset = 0; offset < all_desc.length; offset += 4) {
303
+ const rows = await page(t, admin_h, { limit: 4, offset });
304
+ assert.ok(rows.length <= 4, `admin page at offset ${offset} exceeds limit`);
305
+ admin_pages.push(...rows);
306
+ }
307
+ assert.deepStrictEqual(admin_pages, all_desc, 'admin pages tile the whole list in order');
308
+ // the owner sees its own private rows beside every public one
309
+ const owner_rows = await page(t, owner_h, { limit: 50 });
310
+ assert.deepStrictEqual(owner_rows, all_desc.filter((id) => visible.includes(id) || hidden.indexOf(id) % 2 === 0), 'the owner reads public rows plus its own private ones');
311
+ });
197
312
  test_if(capabilities.cell_crud, 'cell_get without id or path → invalid_params', async () => {
198
313
  const fixture = await setup_test();
199
314
  const bad = await cross_rpc_call(fixture.fresh_transport(), rpc_path, 'cell_get', {}, fixture.create_session_headers());
@@ -271,5 +386,61 @@ export const describe_cell_crud_cross_tests = (options) => {
271
386
  }
272
387
  }
273
388
  });
389
+ describe('mistyped data', () => {
390
+ /** Count every cell, read as the keeper (an admin sees every row). */
391
+ const count_cells = async (t, keeper_headers) => {
392
+ const { cells } = expect_output(await cross_rpc_call(t, rpc_path, 'cell_list', { limit: CELL_LIST_LIMIT_MAX }, keeper_headers), CellListOutput);
393
+ assert.ok(cells.length < CELL_LIST_LIMIT_MAX, 'the count needs a page that holds every cell');
394
+ return cells.length;
395
+ };
396
+ test_if(capabilities.cell_crud, 'cell_create and cell_update refuse it as invalid_params before any cell check', async () => {
397
+ const fixture = await setup_test();
398
+ const writer = await fixture.create_account({ username: 'cell_data_writer' });
399
+ const stranger = await fixture.create_account({ username: 'cell_data_stranger' });
400
+ const t = fixture.fresh_transport();
401
+ const keeper_headers = fixture.create_session_headers();
402
+ const writer_headers = writer.create_session_headers();
403
+ // the keeper's private cell, hidden from the stranger; the keeper
404
+ // creates it so a backend that refuses a non-admin root runs the case
405
+ const hidden = expect_output(await cross_rpc_call(t, rpc_path, 'cell_create', { kind: 'note', data: {} }, keeper_headers), CellCreateOutput).cell.id;
406
+ const missing = crypto.randomUUID();
407
+ const before = await count_cells(t, keeper_headers);
408
+ for (const data of MISTYPED_CELL_DATA) {
409
+ const shown = JSON.stringify(data);
410
+ assert_schema_refusal(await cross_rpc_call(t, rpc_path, 'cell_create', { data }, writer_headers), `cell_create data ${shown}`);
411
+ for (const [cell_id, headers, who] of [
412
+ [missing, writer_headers, 'a missing cell'],
413
+ [hidden, stranger.create_session_headers(), 'a hidden cell']
414
+ ]) {
415
+ assert_schema_refusal(await cross_rpc_call(t, rpc_path, 'cell_update', { cell_id, data }, headers), `cell_update of ${who} data ${shown}`);
416
+ }
417
+ }
418
+ // the control: well-typed, the same call meets the 404 mask, so the
419
+ // 400s above came before the cell check
420
+ assert_cell_not_found(await cross_rpc_call(t, rpc_path, 'cell_update', { cell_id: hidden, data: {} }, stranger.create_session_headers()), 'cell_update of a hidden cell data {}');
421
+ assert.strictEqual(await count_cells(t, keeper_headers), before, 'a refused write wrote a cell');
422
+ });
423
+ test_if(capabilities.cell_crud && capabilities.cell_relations, 'cell_clone refuses it in with_data_patch as invalid_params before any cell check', async () => {
424
+ const fixture = await setup_test();
425
+ const writer = await fixture.create_account({ username: 'cell_patch_writer' });
426
+ const stranger = await fixture.create_account({ username: 'cell_patch_stranger' });
427
+ const t = fixture.fresh_transport();
428
+ const keeper_headers = fixture.create_session_headers();
429
+ const hidden = expect_output(await cross_rpc_call(t, rpc_path, 'cell_create', { kind: 'note', data: {} }, keeper_headers), CellCreateOutput).cell.id;
430
+ const missing = crypto.randomUUID();
431
+ const before = await count_cells(t, keeper_headers);
432
+ for (const with_data_patch of MISTYPED_CELL_DATA) {
433
+ for (const [source_id, headers, who] of [
434
+ [missing, writer.create_session_headers(), 'a missing cell'],
435
+ [hidden, stranger.create_session_headers(), 'a hidden cell']
436
+ ]) {
437
+ assert_schema_refusal(await cross_rpc_call(t, rpc_path, 'cell_clone', { source_id, with_data_patch }, headers), `cell_clone of ${who} with_data_patch ${JSON.stringify(with_data_patch)}`);
438
+ }
439
+ }
440
+ // the control: well-typed, the same clone meets the 404 mask
441
+ assert_cell_not_found(await cross_rpc_call(t, rpc_path, 'cell_clone', { source_id: hidden, with_data_patch: { label: 'patched' } }, stranger.create_session_headers()), 'cell_clone of a hidden cell with_data_patch {label}');
442
+ assert.strictEqual(await count_cells(t, keeper_headers), before, 'a refused clone wrote a cell');
443
+ });
444
+ });
274
445
  });
275
446
  };
@@ -1,64 +1,4 @@
1
1
  import '../assert_dev_env.js';
2
2
  import type { RpcPathCapabilityGatedCrossSuiteOptions } from './setup.js';
3
3
  export declare const describe_cell_gated_create_cross_tests: (options: RpcPathCapabilityGatedCrossSuiteOptions) => void;
4
- /**
5
- * Cross-backend parity for the **`cell_moderate` verb** (the `pending →
6
- * approved | rejected` transition) — root-authority-gated.
7
- *
8
- * Builds a moderated public space (admin) + a `participant`'s `post` (born
9
- * `pending` + private under the `moderation_required: true` policy), then
10
- * proves both spines agree:
11
- *
12
- * - **a root manager (admin) approves** → `moderation: 'approved'` +
13
- * `visibility: 'public'` (the contribution goes live).
14
- * - **the author cannot self-approve** → `403 cell_moderate_forbidden` (the
15
- * author can *view* their own pending cell, so they reach the gate, and are
16
- * denied — moderation authority is over the governing root, not the
17
- * contribution).
18
- * - **a non-viewer is 404-masked** → a stranger who can't see the pending
19
- * contribution gets `cell_not_found`, never learns it exists.
20
- * - **reject** → `moderation: 'rejected'`, visibility stays private.
21
- *
22
- * And that moderation gates reads — a cell's effective audience is its
23
- * visibility or grants **and** its moderation admission (unmoderated or
24
- * `approved`), so a pending or rejected contribution reaches no one past its
25
- * author and admins:
26
- *
27
- * - **an author's self-flip to public admits nobody** — a pending post its
28
- * author makes public stays 404 to anon and a fresh non-admin on `cell_get`,
29
- * and out of their `cell_list`; the author and admin still read it.
30
- * - **rejection holds a public post back** — pending → rejected → public, and
31
- * approved → rejected (approval made it public, rejection leaves visibility
32
- * alone), both 404 past the author; a grant made while the post was approved
33
- * stops admitting once it is rejected, on `cell_get` and `shared_with: 'me'`.
34
- * - **an approved post is live** — the control.
35
- * - **relation reads follow** — a pending post in a public collection is
36
- * omitted from anon `cell_item_list`, beside a live sibling that isn't; at
37
- * the far end of all four relation lists, a pending post is hidden from
38
- * anon even flipped public, and a rejected one from its grant holder.
39
- * - **fact serving follows** — a pending post's fact is 404 to anon, even
40
- * with the post flipped public (also gated on `capabilities.fact_serving`).
41
- *
42
- * And the steward arm — the owner of a **non-admin** root (a parentless
43
- * non-`space` kind carrying the same policy, which the test authorizer leaves
44
- * open) reads the pending posts under it and moderates them:
45
- *
46
- * - **the queue** — `cell_list({root_id, moderation: 'pending'})` and
47
- * `cell_get` (with `can_edit` / `can_grant` false) → 200; a stranger 404s.
48
- * - **moderation** — the root owner approves → 200; the author 403, a
49
- * stranger 404.
50
- * - **the arm stops there** — the root owner's `cell_clone` of the pending
51
- * post and a contribution under it are both 404.
52
- * - **fact serving** — the root owner fetches a pending post's fact → 200,
53
- * anon 404 (also gated on `capabilities.fact_serving`).
54
- *
55
- * And that `cell_grant_create` refuses a pending contribution — **403**
56
- * `cell_grant_unapproved` for its author and an admin, actor- and role-shaped,
57
- * while a non-manager keeps the **404** mask; the same grant lands once the
58
- * post is approved.
59
- *
60
- * Gated on `capabilities.cell_gated_create` — a `pending` contribution only
61
- * exists when the directory authorizer is mounted (reference spine binaries).
62
- */
63
- export declare const describe_cell_moderate_cross_tests: (options: RpcPathCapabilityGatedCrossSuiteOptions) => void;
64
4
  //# sourceMappingURL=cell_gated_create.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cell_gated_create.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/cell_gated_create.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAoE9B,OAAO,KAAK,EAAE,uCAAuC,EAAE,MAAM,YAAY,CAAC;AAqB1E,eAAO,MAAM,sCAAsC,GAClD,SAAS,uCAAuC,KAC9C,IAuTF,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0DG;AACH,eAAO,MAAM,kCAAkC,GAC9C,SAAS,uCAAuC,KAC9C,IAs6BF,CAAC"}
1
+ {"version":3,"file":"cell_gated_create.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/cell_gated_create.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAsD9B,OAAO,KAAK,EAAE,uCAAuC,EAAE,MAAM,YAAY,CAAC;AAQ1E,eAAO,MAAM,sCAAsC,GAClD,SAAS,uCAAuC,KAC9C,IAuTF,CAAC"}