@fuzdev/fuz_app 0.148.0 → 0.150.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 (210) hide show
  1. package/dist/actions/CLAUDE.md +11 -9
  2. package/dist/actions/action_bridge.d.ts +7 -0
  3. package/dist/actions/action_bridge.d.ts.map +1 -1
  4. package/dist/actions/action_bridge.js +10 -0
  5. package/dist/actions/action_event.d.ts.map +1 -1
  6. package/dist/actions/action_event.js +14 -1
  7. package/dist/actions/action_event_types.d.ts +1 -1
  8. package/dist/actions/action_event_types.d.ts.map +1 -1
  9. package/dist/actions/perform_action.d.ts +17 -1
  10. package/dist/actions/perform_action.d.ts.map +1 -1
  11. package/dist/actions/perform_action.js +30 -7
  12. package/dist/actions/register_action_ws.d.ts +8 -2
  13. package/dist/actions/register_action_ws.d.ts.map +1 -1
  14. package/dist/actions/register_action_ws.js +24 -4
  15. package/dist/actions/transports_ws_auth_guard.d.ts +6 -4
  16. package/dist/actions/transports_ws_auth_guard.d.ts.map +1 -1
  17. package/dist/actions/transports_ws_auth_guard.js +9 -6
  18. package/dist/actions/ws_endpoint_spec.d.ts +1 -1
  19. package/dist/auth/CLAUDE.md +72 -33
  20. package/dist/auth/account_action_specs.d.ts +12 -0
  21. package/dist/auth/account_action_specs.d.ts.map +1 -1
  22. package/dist/auth/account_action_specs.js +16 -2
  23. package/dist/auth/account_actions.d.ts.map +1 -1
  24. package/dist/auth/account_actions.js +7 -4
  25. package/dist/auth/actor_lookup_queries.d.ts +3 -2
  26. package/dist/auth/actor_lookup_queries.d.ts.map +1 -1
  27. package/dist/auth/actor_lookup_queries.js +6 -3
  28. package/dist/auth/actor_search_queries.d.ts +5 -2
  29. package/dist/auth/actor_search_queries.d.ts.map +1 -1
  30. package/dist/auth/actor_search_queries.js +11 -4
  31. package/dist/auth/admin_action_specs.d.ts +4 -4
  32. package/dist/auth/admin_action_specs.d.ts.map +1 -1
  33. package/dist/auth/admin_action_specs.js +33 -12
  34. package/dist/auth/admin_actions.d.ts.map +1 -1
  35. package/dist/auth/admin_actions.js +35 -6
  36. package/dist/auth/all_cell_actions.d.ts +11 -2
  37. package/dist/auth/all_cell_actions.d.ts.map +1 -1
  38. package/dist/auth/all_cell_actions.js +2 -1
  39. package/dist/auth/audit_emitter.d.ts +23 -3
  40. package/dist/auth/audit_emitter.d.ts.map +1 -1
  41. package/dist/auth/audit_emitter.js +14 -4
  42. package/dist/auth/audit_log_schema.d.ts +1 -0
  43. package/dist/auth/audit_log_schema.d.ts.map +1 -1
  44. package/dist/auth/audit_log_schema.js +9 -5
  45. package/dist/auth/bootstrap_account.d.ts +25 -1
  46. package/dist/auth/bootstrap_account.d.ts.map +1 -1
  47. package/dist/auth/bootstrap_account.js +37 -4
  48. package/dist/auth/bootstrap_routes.d.ts +3 -2
  49. package/dist/auth/bootstrap_routes.d.ts.map +1 -1
  50. package/dist/auth/bootstrap_routes.js +5 -4
  51. package/dist/auth/cell_action_specs.d.ts +215 -15
  52. package/dist/auth/cell_action_specs.d.ts.map +1 -1
  53. package/dist/auth/cell_action_specs.js +103 -16
  54. package/dist/auth/cell_actions.d.ts +40 -18
  55. package/dist/auth/cell_actions.d.ts.map +1 -1
  56. package/dist/auth/cell_actions.js +126 -19
  57. package/dist/auth/cell_audit_events.d.ts +1 -1
  58. package/dist/auth/cell_audit_events.d.ts.map +1 -1
  59. package/dist/auth/cell_audit_events.js +3 -2
  60. package/dist/auth/cell_audit_metadata.d.ts +11 -0
  61. package/dist/auth/cell_audit_metadata.d.ts.map +1 -1
  62. package/dist/auth/cell_audit_metadata.js +10 -0
  63. package/dist/auth/cell_grant_action_specs.d.ts +7 -0
  64. package/dist/auth/cell_grant_action_specs.d.ts.map +1 -1
  65. package/dist/auth/cell_grant_action_specs.js +7 -0
  66. package/dist/auth/cell_grant_actions.d.ts +36 -4
  67. package/dist/auth/cell_grant_actions.d.ts.map +1 -1
  68. package/dist/auth/cell_grant_actions.js +20 -3
  69. package/dist/auth/credential_type_schema.d.ts +3 -2
  70. package/dist/auth/credential_type_schema.d.ts.map +1 -1
  71. package/dist/auth/credential_type_schema.js +3 -2
  72. package/dist/auth/role_grant_offer_action_specs.d.ts +18 -2
  73. package/dist/auth/role_grant_offer_action_specs.d.ts.map +1 -1
  74. package/dist/auth/role_grant_offer_action_specs.js +30 -6
  75. package/dist/auth/role_grant_offer_actions.d.ts +9 -4
  76. package/dist/auth/role_grant_offer_actions.d.ts.map +1 -1
  77. package/dist/auth/role_grant_offer_actions.js +58 -7
  78. package/dist/auth/role_grant_offer_notifications.d.ts +3 -2
  79. package/dist/auth/role_grant_offer_notifications.d.ts.map +1 -1
  80. package/dist/auth/role_grant_offer_notifications.js +3 -2
  81. package/dist/auth/role_grant_offer_queries.d.ts +20 -0
  82. package/dist/auth/role_grant_offer_queries.d.ts.map +1 -1
  83. package/dist/auth/role_grant_offer_queries.js +35 -0
  84. package/dist/auth/role_grant_queries.d.ts +27 -9
  85. package/dist/auth/role_grant_queries.d.ts.map +1 -1
  86. package/dist/auth/role_grant_queries.js +40 -13
  87. package/dist/auth/role_schema.d.ts +14 -8
  88. package/dist/auth/role_schema.d.ts.map +1 -1
  89. package/dist/auth/role_schema.js +6 -3
  90. package/dist/auth/self_service_role_actions.d.ts.map +1 -1
  91. package/dist/auth/self_service_role_actions.js +20 -0
  92. package/dist/db/CLAUDE.md +9 -2
  93. package/dist/db/cell_ddl.d.ts +9 -1
  94. package/dist/db/cell_ddl.d.ts.map +1 -1
  95. package/dist/db/cell_ddl.js +11 -1
  96. package/dist/db/cell_queries.d.ts +53 -7
  97. package/dist/db/cell_queries.d.ts.map +1 -1
  98. package/dist/db/cell_queries.js +61 -7
  99. package/dist/http/CLAUDE.md +14 -2
  100. package/dist/http/body_limit.d.ts +3 -1
  101. package/dist/http/body_limit.d.ts.map +1 -1
  102. package/dist/http/body_limit.js +6 -1
  103. package/dist/http/error_schemas.d.ts +8 -0
  104. package/dist/http/error_schemas.d.ts.map +1 -1
  105. package/dist/http/error_schemas.js +12 -0
  106. package/dist/http/jsonrpc.d.ts +9 -0
  107. package/dist/http/jsonrpc.d.ts.map +1 -1
  108. package/dist/http/jsonrpc.js +17 -0
  109. package/dist/http/jsonrpc_errors.d.ts +40 -15
  110. package/dist/http/jsonrpc_errors.d.ts.map +1 -1
  111. package/dist/http/jsonrpc_errors.js +99 -35
  112. package/dist/http/proxy.d.ts +4 -2
  113. package/dist/http/proxy.d.ts.map +1 -1
  114. package/dist/http/proxy.js +7 -2
  115. package/dist/http/surface.d.ts +3 -1
  116. package/dist/http/surface.d.ts.map +1 -1
  117. package/dist/http/surface.js +7 -4
  118. package/dist/realtime/sse_auth_guard.d.ts.map +1 -1
  119. package/dist/realtime/sse_auth_guard.js +3 -2
  120. package/dist/schema_meta.d.ts +92 -1
  121. package/dist/schema_meta.d.ts.map +1 -1
  122. package/dist/schema_meta.js +117 -0
  123. package/dist/server/app_server.d.ts +13 -5
  124. package/dist/server/app_server.d.ts.map +1 -1
  125. package/dist/server/app_server.js +32 -8
  126. package/dist/testing/CLAUDE.md +196 -82
  127. package/dist/testing/adversarial_input_cases.d.ts +67 -7
  128. package/dist/testing/adversarial_input_cases.d.ts.map +1 -1
  129. package/dist/testing/adversarial_input_cases.js +210 -165
  130. package/dist/testing/app_server.d.ts +3 -1
  131. package/dist/testing/app_server.d.ts.map +1 -1
  132. package/dist/testing/audit_drift_guard.d.ts +3 -2
  133. package/dist/testing/audit_drift_guard.d.ts.map +1 -1
  134. package/dist/testing/audit_drift_guard.js +5 -3
  135. package/dist/testing/cross_backend/actor_lookup.d.ts.map +1 -1
  136. package/dist/testing/cross_backend/actor_lookup.js +27 -0
  137. package/dist/testing/cross_backend/audit_cross_helpers.d.ts +6 -0
  138. package/dist/testing/cross_backend/audit_cross_helpers.d.ts.map +1 -1
  139. package/dist/testing/cross_backend/audit_cross_helpers.js +11 -0
  140. package/dist/testing/cross_backend/capabilities.d.ts +29 -5
  141. package/dist/testing/cross_backend/capabilities.d.ts.map +1 -1
  142. package/dist/testing/cross_backend/capabilities.js +10 -6
  143. package/dist/testing/cross_backend/cell_crud.d.ts.map +1 -1
  144. package/dist/testing/cross_backend/cell_crud.js +117 -2
  145. package/dist/testing/cross_backend/cell_gated_create.d.ts.map +1 -1
  146. package/dist/testing/cross_backend/cell_gated_create.js +109 -13
  147. package/dist/testing/cross_backend/cell_moderate.d.ts +7 -1
  148. package/dist/testing/cross_backend/cell_moderate.d.ts.map +1 -1
  149. package/dist/testing/cross_backend/cell_moderate.js +68 -4
  150. package/dist/testing/cross_backend/cell_ref_admission.d.ts.map +1 -1
  151. package/dist/testing/cross_backend/cell_ref_admission.js +18 -9
  152. package/dist/testing/cross_backend/conformance_table.d.ts +5 -0
  153. package/dist/testing/cross_backend/conformance_table.d.ts.map +1 -1
  154. package/dist/testing/cross_backend/conformance_table.js +12 -10
  155. package/dist/testing/cross_backend/cross_rpc.d.ts +3 -1
  156. package/dist/testing/cross_backend/cross_rpc.d.ts.map +1 -1
  157. package/dist/testing/cross_backend/cross_rpc.js +2 -2
  158. package/dist/testing/cross_backend/default_backend_configs.d.ts +9 -7
  159. package/dist/testing/cross_backend/default_backend_configs.d.ts.map +1 -1
  160. package/dist/testing/cross_backend/default_backend_configs.js +3 -3
  161. package/dist/testing/cross_backend/differential.d.ts +7 -0
  162. package/dist/testing/cross_backend/differential.d.ts.map +1 -1
  163. package/dist/testing/cross_backend/differential.js +17 -0
  164. package/dist/testing/cross_backend/expected_schema.json +1 -0
  165. package/dist/testing/cross_backend/full_spine_mount.d.ts.map +1 -1
  166. package/dist/testing/cross_backend/full_spine_mount.js +5 -4
  167. package/dist/testing/cross_backend/role_grant_offer_lifecycle.d.ts.map +1 -1
  168. package/dist/testing/cross_backend/role_grant_offer_lifecycle.js +74 -2
  169. package/dist/testing/cross_backend/rpc_adversarial.d.ts +9 -0
  170. package/dist/testing/cross_backend/rpc_adversarial.d.ts.map +1 -1
  171. package/dist/testing/cross_backend/rpc_adversarial.js +16 -6
  172. package/dist/testing/cross_backend/rust_spine_consumer_surface.d.ts +1 -1
  173. package/dist/testing/cross_backend/rust_spine_stub_backend_config.d.ts.map +1 -1
  174. package/dist/testing/cross_backend/rust_spine_stub_backend_config.js +6 -3
  175. package/dist/testing/cross_backend/setup.d.ts +2 -2
  176. package/dist/testing/cross_backend/spine_suites.d.ts +85 -5
  177. package/dist/testing/cross_backend/spine_suites.d.ts.map +1 -1
  178. package/dist/testing/cross_backend/spine_suites.js +291 -20
  179. package/dist/testing/cross_backend/spine_surface_constants.d.ts +15 -0
  180. package/dist/testing/cross_backend/spine_surface_constants.d.ts.map +1 -1
  181. package/dist/testing/cross_backend/spine_surface_constants.js +24 -0
  182. package/dist/testing/cross_backend/test_cell_gated_create_authorize.d.ts +18 -19
  183. package/dist/testing/cross_backend/test_cell_gated_create_authorize.d.ts.map +1 -1
  184. package/dist/testing/cross_backend/test_cell_gated_create_authorize.js +66 -42
  185. package/dist/testing/cross_backend/testing_backdoor.d.ts +27 -4
  186. package/dist/testing/cross_backend/testing_backdoor.d.ts.map +1 -1
  187. package/dist/testing/cross_backend/testing_backdoor.js +136 -41
  188. package/dist/testing/cross_backend/testing_reset_actions.d.ts +30 -15
  189. package/dist/testing/cross_backend/testing_reset_actions.d.ts.map +1 -1
  190. package/dist/testing/cross_backend/testing_reset_actions.js +52 -35
  191. package/dist/testing/cross_backend/transport_composition.js +3 -3
  192. package/dist/testing/cross_backend/ts_spine_backend_config.d.ts.map +1 -1
  193. package/dist/testing/cross_backend/ts_spine_backend_config.js +6 -3
  194. package/dist/testing/rpc_attack_surface.d.ts +10 -0
  195. package/dist/testing/rpc_attack_surface.d.ts.map +1 -1
  196. package/dist/testing/rpc_attack_surface.js +15 -3
  197. package/dist/testing/rpc_envelope_cases.d.ts +5 -2
  198. package/dist/testing/rpc_envelope_cases.d.ts.map +1 -1
  199. package/dist/testing/rpc_envelope_cases.js +4 -1
  200. package/dist/testing/rpc_round_trip.js +3 -3
  201. package/dist/testing/schema_generators.d.ts +99 -2
  202. package/dist/testing/schema_generators.d.ts.map +1 -1
  203. package/dist/testing/schema_generators.js +244 -76
  204. package/dist/testing/stubs.d.ts +4 -3
  205. package/dist/testing/stubs.d.ts.map +1 -1
  206. package/dist/testing/stubs.js +6 -4
  207. package/dist/zod.d.ts +9 -0
  208. package/dist/zod.d.ts.map +1 -1
  209. package/dist/zod.js +20 -0
  210. package/package.json +1 -1
@@ -17,7 +17,14 @@ import '../assert_dev_env.js';
17
17
  *
18
18
  * - `exclude` names a suite with the reason it can't run on this backend; the
19
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.
20
+ * stated in code and visible in the report. `testing_backdoor` can't be
21
+ * excluded, by suite or by case, nor its `capabilities.testing_backdoors`
22
+ * changed: it checks the declaration the backdoor gating reads.
23
+ * - `exclude_cases` names single tests of a suite that does run, each by its
24
+ * name path (describe titles and test name, joined with `' > '`) with a
25
+ * required reason; one `beforeEach` skips them at run time, so each shows as
26
+ * skipped with its reason, and an entry matching no collected test of its
27
+ * suite fails the closing check test.
21
28
  * - `overrides` replaces a suite's derived options, field by field (a shallow
22
29
  * merge over what the handle gives) — a role list the backend's WS upgrade
23
30
  * requires, an `xfail` for a tracked divergence, a narrower capability set.
@@ -25,7 +32,10 @@ import '../assert_dev_env.js';
25
32
  * built on a derived value. A required option the merge leaves `undefined`
26
33
  * throws at collection.
27
34
  * - `rpc_success_fixtures` / `rpc_skip_methods` / `rpc_input_overrides` go to
28
- * the standard bundle's RPC round-trip.
35
+ * the standard bundle's RPC round-trip; `rpc_input_overrides` also seeds
36
+ * `rpc_adversarial`'s params cases (each override is the valid base they
37
+ * break one field of). A key naming a method on neither the declared surface
38
+ * nor `live_rpc_endpoints` throws at collection.
29
39
  * - `ws_required_roles` names the roles the backend's WS upgrade requires, so the
30
40
  * suites that open sockets for accounts they create give them those roles.
31
41
  * - `suite_roles` names the roles the role-shaped suites use when the backend's
@@ -41,6 +51,15 @@ import '../assert_dev_env.js';
41
51
  * config's `SECRET_FUZ_COOKIE_KEYS`), else from `overrides`; when neither has
42
52
  * it, the call throws naming the suite — provide it or exclude the suite.
43
53
  *
54
+ * **Backdoors.** The backend's `capabilities.testing_backdoors` must declare
55
+ * `SPINE_SUITES_REQUIRED_BACKDOORS` (the per-test reset and the audit
56
+ * barrier), and `_testing_put_fact` when it declares `fact_serving`; the call
57
+ * throws otherwise. A suite every case of which drives another backdoor
58
+ * (`credential_deadline`, `origin_conformance`, `ws_outbound_overflow`) skips
59
+ * itself on a backend not declaring it, shown like an exclude with a reason
60
+ * naming the backdoor — so an exclude, override or `exclude_cases` entry for
61
+ * it is refused as dead.
62
+ *
44
63
  * **Not in the one call** (`STANDALONE_CROSS_SUITES`, with the reasons): the
45
64
  * suites that need two handles (the differential), a backend spawned with live
46
65
  * limiters (`login_security`, `ws_action_rate_limit` — the standard suites would
@@ -48,11 +67,13 @@ import '../assert_dev_env.js';
48
67
  * cases. Each keeps its own entry point.
49
68
  *
50
69
  * Suites are registered without a wrapping `describe`, so their test names are
51
- * the same as when each is called on its own.
70
+ * the same as when each is called on its own — and an `exclude_cases` path is
71
+ * the name the reporter prints after the file and any `describe` wrapping the
72
+ * call.
52
73
  *
53
74
  * @module
54
75
  */
55
- import { describe, test } from 'vitest';
76
+ import { beforeAll, beforeEach, describe, test, TestRunner } from 'vitest';
56
77
  import { ROLE_KEEPER, ROLE_ADMIN } from '../../auth/role_schema.js';
57
78
  import { resolve_rpc_endpoints_for_setup } from '../rpc_helpers.js';
58
79
  import { describe_account_lifecycle_cross_tests } from './account_lifecycle.js';
@@ -161,6 +182,16 @@ export const STANDALONE_CROSS_SUITES = {
161
182
  ws_action_rate_limit: 'needs a backend spawned with the action limiters enabled, which the standard suites would exhaust',
162
183
  conformance_table: "a runner over the consumer's own cases, not a suite"
163
184
  };
185
+ /**
186
+ * The backdoors `describe_spine_cross_suites` requires of every backend, since
187
+ * the suites share them: `_testing_reset` is every `setup_test`'s per-test
188
+ * reset, and `_testing_drain_effects` the barrier every audit read waits on. A
189
+ * backend whose `capabilities.testing_backdoors` lacks one fails at collection.
190
+ */
191
+ export const SPINE_SUITES_REQUIRED_BACKDOORS = Object.freeze([
192
+ '_testing_reset',
193
+ '_testing_drain_effects'
194
+ ]);
164
195
  /**
165
196
  * The suite options a handle's `config` supplies — the fields most cross
166
197
  * suites take beside `setup_test`. For a suite called on its own:
@@ -268,7 +299,8 @@ const SUITE_ENTRIES = {
268
299
  ws_account_roles: c.options.ws_required_roles
269
300
  }),
270
301
  describe: describe_credential_deadline_cross_tests,
271
- required: { setup_test: true, capabilities: true, base_url: true, ws_path: true }
302
+ required: { setup_test: true, capabilities: true, base_url: true, ws_path: true },
303
+ backdoors: ['_testing_shorten_credential_expiry']
272
304
  },
273
305
  credential_header_robustness: {
274
306
  derive: (c) => ({
@@ -301,7 +333,8 @@ const SUITE_ENTRIES = {
301
333
  origin_conformance: {
302
334
  derive: (c) => ({ setup_test: c.setup(), rpc_path: c.config.rpc_path }),
303
335
  describe: describe_origin_conformance_cross_tests,
304
- required: { setup_test: true }
336
+ required: { setup_test: true },
337
+ backdoors: ['_testing_origin_check']
305
338
  },
306
339
  origin_scope: {
307
340
  derive: (c) => ({
@@ -385,7 +418,8 @@ const SUITE_ENTRIES = {
385
418
  surface_source: c.options.surface_source,
386
419
  live_rpc_endpoints: c.options.live_rpc_endpoints &&
387
420
  resolve_rpc_endpoints_for_setup(c.options.live_rpc_endpoints, c.options.session_options),
388
- rpc_path: c.config.rpc_path
421
+ rpc_path: c.config.rpc_path,
422
+ input_overrides: c.options.rpc_input_overrides
389
423
  }),
390
424
  describe: describe_rpc_adversarial_cross_tests,
391
425
  required: { setup_test: true, surface_source: true }
@@ -451,9 +485,9 @@ const SUITE_ENTRIES = {
451
485
  }
452
486
  },
453
487
  testing_backdoor: {
454
- derive: (c) => ({ setup_test: c.setup(), rpc_path: c.config.rpc_path, ws: c.ws }),
488
+ derive: (c) => ({ ...rpc_gated(c), ws: c.ws }),
455
489
  describe: describe_testing_backdoor_cross_tests,
456
- required: { setup_test: true }
490
+ required: { setup_test: true, capabilities: true }
457
491
  },
458
492
  token_lifetime: {
459
493
  derive: (c) => ({ setup_test: c.setup(), rpc_path: c.config.rpc_path }),
@@ -506,7 +540,8 @@ const SUITE_ENTRIES = {
506
540
  rpc_path: c.config.rpc_path
507
541
  }),
508
542
  describe: describe_ws_outbound_overflow_cross_tests,
509
- required: { setup_test: true, capabilities: true, base_url: true, ws_path: true }
543
+ required: { setup_test: true, capabilities: true, base_url: true, ws_path: true },
544
+ backdoors: ['_testing_flood_notifications']
510
545
  },
511
546
  ws_role_gated: {
512
547
  // the reference spines' role-gated endpoint; a backend mounting its own
@@ -553,12 +588,62 @@ const merge_setup_options = (base, seed) => ({
553
588
  extra_accounts: [...(base?.extra_accounts ?? []), ...(seed?.extra_accounts ?? [])],
554
589
  extra_actors: [...(base?.extra_actors ?? []), ...(seed?.extra_actors ?? [])]
555
590
  });
591
+ /**
592
+ * The backdoors every case of `name` drives beyond
593
+ * `SPINE_SUITES_REQUIRED_BACKDOORS` — a backend not declaring one skips the
594
+ * suite.
595
+ *
596
+ * @param name - the suite
597
+ * @returns its `SuiteEntry.backdoors`, empty for a suite needing none
598
+ * @internal
599
+ */
600
+ export const get_spine_suite_backdoors = (name) => SUITE_ENTRIES[name].backdoors ?? [];
556
601
  const is_suite_name = (name) => SUITE_NAMES.includes(name);
557
602
  /**
558
- * Refuse an exclude with an empty reason, an unknown suite name, and a suite
559
- * both excluded and overridden — before anything is registered.
603
+ * Each suite whose backdoors `declared` lacks, with the generated reason it is
604
+ * skipped — the suites whose every case drives a backdoor (`SuiteEntry.backdoors`).
560
605
  */
561
- const validate_spine_cross_suites_options = (options) => {
606
+ const to_backdoor_skips = (declared) => {
607
+ const skips = new Map();
608
+ for (const name of SUITE_NAMES) {
609
+ const missing = get_spine_suite_backdoors(name).filter((m) => !declared.includes(m));
610
+ if (missing.length > 0) {
611
+ skips.set(name, `needs ${missing.map((m) => `\`${m}\``).join(', ')}, which capabilities.testing_backdoors doesn't declare`);
612
+ }
613
+ }
614
+ return skips;
615
+ };
616
+ /**
617
+ * Refuse an exclude with an empty reason, an unknown suite name, a suite both
618
+ * excluded and overridden, a backend missing a backdoor the suites share, an
619
+ * exclude or override of a suite that skips itself for an undeclared
620
+ * backdoor, any exclusion of `testing_backdoor`, and an `exclude_cases` entry
621
+ * naming a suite the call doesn't run or carrying no reason — before anything
622
+ * is registered.
623
+ */
624
+ const validate_spine_cross_suites_options = (options, declared, backdoor_skips, capabilities) => {
625
+ if (options.rpc_input_overrides?.size) {
626
+ // a key the round-trip (the declared surface) and `rpc_adversarial` (that
627
+ // and the live mount) both lack would be ignored silently — a typo
628
+ const methods = new Set();
629
+ for (const endpoint of options.surface_source.surface.rpc_endpoints) {
630
+ for (const method of endpoint.methods)
631
+ methods.add(method.name);
632
+ }
633
+ if (options.live_rpc_endpoints) {
634
+ const live = resolve_rpc_endpoints_for_setup(options.live_rpc_endpoints, options.session_options);
635
+ for (const endpoint of live) {
636
+ for (const action of endpoint.actions)
637
+ methods.add(action.spec.method);
638
+ }
639
+ }
640
+ for (const method of options.rpc_input_overrides.keys()) {
641
+ if (!methods.has(method)) {
642
+ throw new Error(`describe_spine_cross_suites: rpc_input_overrides names '${method}', ` +
643
+ `a method on neither the declared surface nor the live mount`);
644
+ }
645
+ }
646
+ }
562
647
  for (const [name, reason] of Object.entries(options.exclude ?? {})) {
563
648
  if (!is_suite_name(name)) {
564
649
  throw new Error(`describe_spine_cross_suites: exclude names unknown suite '${name}'`);
@@ -569,11 +654,58 @@ const validate_spine_cross_suites_options = (options) => {
569
654
  if (options.overrides?.[name] !== undefined) {
570
655
  throw new Error(`describe_spine_cross_suites: '${name}' is both excluded and overridden`);
571
656
  }
657
+ if (name === 'testing_backdoor') {
658
+ throw new Error("describe_spine_cross_suites: 'testing_backdoor' can't be excluded — it checks the " +
659
+ 'capabilities.testing_backdoors declaration the other suites gate on');
660
+ }
661
+ const skip = backdoor_skips.get(name);
662
+ if (skip !== undefined) {
663
+ throw new Error(`describe_spine_cross_suites: exclude '${name}' is redundant — the suite skips itself (${skip})`);
664
+ }
572
665
  }
573
666
  for (const name of Object.keys(options.overrides ?? {})) {
574
667
  if (!is_suite_name(name)) {
575
668
  throw new Error(`describe_spine_cross_suites: overrides names unknown suite '${name}'`);
576
669
  }
670
+ const skip = backdoor_skips.get(name);
671
+ if (skip !== undefined) {
672
+ throw new Error(`describe_spine_cross_suites: overrides names '${name}', which skips itself (${skip})`);
673
+ }
674
+ }
675
+ for (const [name, cases] of Object.entries(options.exclude_cases ?? {})) {
676
+ if (!is_suite_name(name)) {
677
+ throw new Error(`describe_spine_cross_suites: exclude_cases names unknown suite '${name}'`);
678
+ }
679
+ if (options.exclude?.[name] !== undefined) {
680
+ throw new Error(`describe_spine_cross_suites: '${name}' is excluded, so its exclude_cases entries name nothing`);
681
+ }
682
+ if (name === 'testing_backdoor') {
683
+ throw new Error("describe_spine_cross_suites: exclude_cases can't name 'testing_backdoor' — it checks the " +
684
+ 'capabilities.testing_backdoors declaration the other suites gate on, and a declared ' +
685
+ 'backdoor failing its credential row is a bug, not a case to skip');
686
+ }
687
+ const skip = backdoor_skips.get(name);
688
+ if (skip !== undefined) {
689
+ throw new Error(`describe_spine_cross_suites: exclude_cases names '${name}', which skips itself (${skip})`);
690
+ }
691
+ const entries = Object.entries(cases ?? {});
692
+ if (entries.length === 0) {
693
+ throw new Error(`describe_spine_cross_suites: exclude_cases '${name}' names no test`);
694
+ }
695
+ for (const [test_name, reason] of entries) {
696
+ if (typeof reason !== 'string' || reason.trim() === '') {
697
+ throw new Error(`describe_spine_cross_suites: exclude_cases '${name}' › '${test_name}' needs a reason`);
698
+ }
699
+ }
700
+ }
701
+ const missing = SPINE_SUITES_REQUIRED_BACKDOORS.filter((m) => !declared.includes(m));
702
+ if (missing.length > 0) {
703
+ throw new Error(`describe_spine_cross_suites: capabilities.testing_backdoors must declare ${missing.join(', ')} ` +
704
+ '— every suite resets through _testing_reset and reads audit rows behind _testing_drain_effects');
705
+ }
706
+ if (capabilities.fact_serving && !declared.includes('_testing_put_fact')) {
707
+ throw new Error('describe_spine_cross_suites: capabilities.fact_serving needs _testing_put_fact in ' +
708
+ 'capabilities.testing_backdoors — the fact suites seed through it');
577
709
  }
578
710
  };
579
711
  const run_suite = (name, context) => {
@@ -589,21 +721,146 @@ const run_suite = (name, context) => {
589
721
  `nor the override gives — pass \`overrides.${name}\` with it or exclude '${name}' with a reason`);
590
722
  }
591
723
  }
724
+ // the backdoor suite checks the declaration the gating read, so an override
725
+ // can't hand it another; it reads nothing else of `capabilities`, so a copy
726
+ // keeping the list passes
727
+ if (name === 'testing_backdoor') {
728
+ const checked = suite_options.capabilities
729
+ .testing_backdoors;
730
+ const declared = context.config.capabilities.testing_backdoors;
731
+ // the same entries, each as often, in any order
732
+ if ([...checked].sort().join(' ') !== [...declared].sort().join(' ')) {
733
+ throw new Error("describe_spine_cross_suites: overrides can't change 'testing_backdoor' " +
734
+ 'capabilities.testing_backdoors — it checks the declaration the other suites gate on');
735
+ }
736
+ }
592
737
  entry.describe(suite_options);
593
738
  };
739
+ /**
740
+ * Where `task` sits below `root`: its name path (its describe titles and its
741
+ * name) and its top-level ancestor, one of `root`'s own tasks — or `null`
742
+ * outside `root`.
743
+ */
744
+ const locate_task = (task, root) => {
745
+ const path = [];
746
+ let current = task;
747
+ for (;;) {
748
+ path.unshift(current.name);
749
+ // a test or describe at a file's top level has no `suite`, only its `file`
750
+ const parent = current.suite ?? current.file;
751
+ if (parent === root)
752
+ return { path, top: current };
753
+ if (!parent || parent === current)
754
+ return null;
755
+ current = parent;
756
+ }
757
+ };
758
+ /** Every test under `task`, as name paths starting with `prefix`. */
759
+ const collect_test_paths = (task, prefix, out) => {
760
+ const path = [...prefix, task.name];
761
+ if (task.type === 'suite') {
762
+ for (const child of task.tasks)
763
+ collect_test_paths(child, path, out);
764
+ }
765
+ else {
766
+ out.add(path.join(' > '));
767
+ }
768
+ };
769
+ /**
770
+ * Check every `exclude_cases` entry against the test paths each suite
771
+ * collected — the static half of the case exclusions, which the closing test
772
+ * `register_spine_case_exclusions` registers runs.
773
+ *
774
+ * @param exclude_cases - the entries, by suite
775
+ * @param collected - each run suite's collected test paths
776
+ * @throws Error - naming every entry whose suite collected no test at its path
777
+ * @internal
778
+ */
779
+ export const check_spine_case_exclusions = (exclude_cases, collected) => {
780
+ const dead = [];
781
+ for (const [name, cases] of Object.entries(exclude_cases)) {
782
+ const paths = collected.get(name);
783
+ for (const test_name of Object.keys(cases ?? {})) {
784
+ if (!paths?.has(test_name))
785
+ dead.push(`${name} › ${test_name}`);
786
+ }
787
+ }
788
+ if (dead.length > 0) {
789
+ throw new Error(`exclude_cases entries naming no collected test of their suite (a renamed or removed ` +
790
+ `test, or a path missing a describe title): ${dead.join('; ')}`);
791
+ }
792
+ };
793
+ /**
794
+ * Skip the `exclude_cases` tests, and fail on an entry no collected test has.
795
+ * `describe_spine_cross_suites` calls it after registering the suites, in the
796
+ * same suite.
797
+ *
798
+ * One `beforeEach` on the calling suite: it finds the test's top-level task
799
+ * among the ranges the suites registered, and calls `ctx.skip(reason)` when
800
+ * that suite's entries name the test's path — so the suite files stay as they
801
+ * are, and the test shows as skipped with its reason. A closing test holds
802
+ * every entry to a test its suite collected (`check_spine_case_exclusions`;
803
+ * the paths are read at collection, so a filtered run still checks them).
804
+ * A skipped test's own `beforeEach` hooks don't run, but its `afterEach`
805
+ * hooks and its suite's `beforeAll` still do.
806
+ *
807
+ * @param exclude_cases - the entries, by suite
808
+ * @param ranges - each run suite's top-level tasks in the calling suite
809
+ * @internal
810
+ */
811
+ export const register_spine_case_exclusions = (exclude_cases, ranges) => {
812
+ let root;
813
+ const collected = new Map();
814
+ const suite_of = (index) => ranges.find((r) => index >= r.start && index < r.end)?.name;
815
+ // vitest passes the suite a hook is registered on as the second argument,
816
+ // and requires the first be destructured
817
+ // eslint-disable-next-line no-empty-pattern
818
+ beforeAll(({}, suite) => {
819
+ root = suite;
820
+ for (const range of ranges) {
821
+ const paths = new Set();
822
+ for (const task of suite.tasks.slice(range.start, range.end)) {
823
+ collect_test_paths(task, [], paths);
824
+ }
825
+ collected.set(range.name, paths);
826
+ }
827
+ });
828
+ beforeEach((ctx) => {
829
+ if (!root)
830
+ return;
831
+ const located = locate_task(ctx.task, root);
832
+ if (!located)
833
+ return;
834
+ const name = suite_of(root.tasks.indexOf(located.top));
835
+ if (name === undefined)
836
+ return;
837
+ const reason = exclude_cases[name]?.[located.path.join(' > ')];
838
+ if (reason !== undefined)
839
+ ctx.skip(`excluded on this backend: ${reason}`);
840
+ });
841
+ test('spine cross suites: every exclude_cases entry names a collected test', () => {
842
+ check_spine_case_exclusions(exclude_cases, collected);
843
+ });
844
+ };
594
845
  /**
595
846
  * Run every shipped single-backend cross suite against one spawned backend —
596
847
  * see the module doc for what the options add and what stays outside.
597
848
  *
598
849
  * @param handle - the backend, as `inject_backend_handle()` returns it
599
- * @param options - the declared surface, plus excludes and overrides
850
+ * @param options - the declared surface, plus excludes, case exclusions and overrides
600
851
  * @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
852
+ * both excluded and overridden, an excluded `testing_backdoor` (or one of
853
+ * its cases, or an override changing its `capabilities.testing_backdoors`), an exclude,
854
+ * override or `exclude_cases` entry for a suite that skips itself or isn't
855
+ * run, a backend not declaring `SPINE_SUITES_REQUIRED_BACKDOORS` (or
856
+ * `_testing_put_fact` with `fact_serving`), or a suite missing an input the
857
+ * handle doesn't carry
603
858
  */
604
859
  export const describe_spine_cross_suites = (handle, options) => {
605
- validate_spine_cross_suites_options(options);
606
860
  const config = to_cross_suite_options(handle);
861
+ const declared = config.capabilities.testing_backdoors;
862
+ const backdoor_skips = to_backdoor_skips(declared);
863
+ validate_spine_cross_suites_options(options, declared, backdoor_skips, config.capabilities);
607
864
  const context = {
608
865
  handle,
609
866
  config,
@@ -611,15 +868,29 @@ export const describe_spine_cross_suites = (handle, options) => {
611
868
  setup: (seed) => default_cross_process_setup(handle, merge_setup_options(options.setup, seed)),
612
869
  ws: config.capabilities.ws ? { base_url: config.base_url, ws_path: config.ws_path } : undefined
613
870
  };
614
- const excluded = Object.entries(options.exclude ?? {});
871
+ // each suite's top-level tasks, by index, so the case exclusions know which
872
+ // suite a test belongs to
873
+ const collector = TestRunner.getCurrentSuite();
874
+ const ranges = [];
875
+ const skipped = Object.entries(options.exclude ?? {});
615
876
  for (const name of SUITE_NAMES) {
616
877
  if (options.exclude?.[name] !== undefined)
617
878
  continue;
879
+ const skip = backdoor_skips.get(name);
880
+ if (skip !== undefined) {
881
+ skipped.push([name, skip]);
882
+ continue;
883
+ }
884
+ const start = collector.tasks.length;
618
885
  run_suite(name, context);
886
+ ranges.push({ name, start, end: collector.tasks.length });
887
+ }
888
+ if (Object.keys(options.exclude_cases ?? {}).length > 0) {
889
+ register_spine_case_exclusions(options.exclude_cases, ranges);
619
890
  }
620
- if (excluded.length > 0) {
891
+ if (skipped.length > 0) {
621
892
  describe('spine cross suites excluded on this backend', () => {
622
- for (const [name, reason] of excluded)
893
+ for (const [name, reason] of skipped)
623
894
  test.skip(`${name}: ${reason}`, () => { });
624
895
  });
625
896
  }
@@ -13,6 +13,21 @@ export declare const TESTING_ACTION_AUTH: {
13
13
  readonly actor: "none";
14
14
  readonly credential_types: readonly ["daemon_token"];
15
15
  };
16
+ /**
17
+ * Every `_testing_*` backdoor the shipped cross suites know: the daemon-token
18
+ * actions a test binary may mount for the harness to drive. The one list a
19
+ * backend's `capabilities.testing_backdoors` declares from, the
20
+ * testing-backdoor suite probes, and `describe_spine_cross_suites` gates suites
21
+ * on. A consumer's own seams stay off it — the testing-backdoor suite takes
22
+ * those as `extra_methods`.
23
+ *
24
+ * `spine_surface_constants.testing_backdoors.test.ts` holds it to the `_testing_*` methods
25
+ * fuz_app's spine binary mounts, so an action added there fails until it is
26
+ * listed here.
27
+ */
28
+ export declare const TESTING_BACKDOOR_METHODS: readonly ["_testing_reset", "_testing_drain_effects", "_testing_mint_session", "_testing_put_fact", "_testing_flood_notifications", "_testing_schema_snapshot", "_testing_migration_tracker", "_testing_action_manifest", "_testing_origin_check", "_testing_shorten_credential_expiry"];
29
+ /** A `_testing_*` backdoor the shipped cross suites know — see `TESTING_BACKDOOR_METHODS`. */
30
+ export type TestingBackdoorMethod = (typeof TESTING_BACKDOOR_METHODS)[number];
16
31
  /** RPC endpoint mount path — matches the binary's `/api/rpc`. */
17
32
  export declare const SPINE_RPC_PATH = "/api/rpc";
18
33
  /** Ungated WebSocket endpoint mount path — matches the binaries' `/api/ws`. */
@@ -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,+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"}
1
+ {"version":3,"file":"spine_surface_constants.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/spine_surface_constants.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AA4B9B;;;;;;;;GAQG;AACH,eAAO,MAAM,mBAAmB;;;;CAIF,CAAC;AAE/B;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,wBAAwB,0RAW3B,CAAC;AAEX,8FAA8F;AAC9F,MAAM,MAAM,qBAAqB,GAAG,CAAC,OAAO,wBAAwB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE9E,iEAAiE;AACjE,eAAO,MAAM,cAAc,aAAa,CAAC;AAEzC,+EAA+E;AAC/E,eAAO,MAAM,aAAa,YAAY,CAAC;AAEvC;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,iBAAiB,CAAC;AAExD,wBAAwB;AACxB,eAAO,MAAM,wBAAwB,uBAAuB,CAAC;AAE7D,yBAAyB;AACzB,eAAO,MAAM,yBAAyB,wBAAwB,CAAC;AAE/D,kCAAkC;AAClC,eAAO,MAAM,2BAA2B,0BAA0B,CAAC;AAEnE,iCAAiC;AACjC,eAAO,MAAM,yBAAyB,wBAAwB,CAAC;AAE/D,yBAAyB;AACzB,eAAO,MAAM,yBAAyB,wBAAwB,CAAC;AAE/D,yEAAyE;AACzE,eAAO,MAAM,4BAA4B,2BAA2B,CAAC;AAErE;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,4BAA4B,CAAC;AAExD;;;;;;;GAOG;AACH,eAAO,MAAM,8BAA8B,QAAc,CAAC;AAE1D;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,gBAAgB,CAAC;AAEpD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,sBAAsB,gBAAgB,CAAC;AAEpD;;;;;;;;;GASG;AACH,eAAO,MAAM,wBAAwB,kBAAkB,CAAC;AAExD;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB,EAAE,aAAa,CAAC,MAAM,CAG1D,CAAC;AAEH;;;;;;;;;;GAUG;AACH,eAAO,MAAM,yBAAyB,EAAE,GAAwD,CAAC;AAEjG;;;;;;;GAOG;AACH,eAAO,MAAM,4BAA4B,iCAAiC,CAAC;AAE3E;;;;;;;;GAQG;AACH,eAAO,MAAM,6BAA6B,kCAAkC,CAAC;AAE7E;;;;;;GAMG;AACH,eAAO,MAAM,kCAAkC,uCAAuC,CAAC;AAEvF;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,6BAA6B,CAAC"}
@@ -13,6 +13,30 @@ export const TESTING_ACTION_AUTH = {
13
13
  actor: 'none',
14
14
  credential_types: ['daemon_token']
15
15
  };
16
+ /**
17
+ * Every `_testing_*` backdoor the shipped cross suites know: the daemon-token
18
+ * actions a test binary may mount for the harness to drive. The one list a
19
+ * backend's `capabilities.testing_backdoors` declares from, the
20
+ * testing-backdoor suite probes, and `describe_spine_cross_suites` gates suites
21
+ * on. A consumer's own seams stay off it — the testing-backdoor suite takes
22
+ * those as `extra_methods`.
23
+ *
24
+ * `spine_surface_constants.testing_backdoors.test.ts` holds it to the `_testing_*` methods
25
+ * fuz_app's spine binary mounts, so an action added there fails until it is
26
+ * listed here.
27
+ */
28
+ export const TESTING_BACKDOOR_METHODS = [
29
+ '_testing_reset',
30
+ '_testing_drain_effects',
31
+ '_testing_mint_session',
32
+ '_testing_put_fact',
33
+ '_testing_flood_notifications',
34
+ '_testing_schema_snapshot',
35
+ '_testing_migration_tracker',
36
+ '_testing_action_manifest',
37
+ '_testing_origin_check',
38
+ '_testing_shorten_credential_expiry'
39
+ ];
16
40
  /** RPC endpoint mount path — matches the binary's `/api/rpc`. */
17
41
  export const SPINE_RPC_PATH = '/api/rpc';
18
42
  /** Ungated WebSocket endpoint mount path — matches the binaries' `/api/ws`. */
@@ -9,38 +9,37 @@ export declare const SPACE_CELL_KIND = "space";
9
9
  */
10
10
  export declare const PARTICIPATION_ROLE = "participant";
11
11
  /**
12
- * A space `data.policy` mirroring the test ladder: gated `post` (moderated) +
12
+ * A space `policy` mirroring the test ladder: gated `post` (moderated) +
13
13
  * `react` (live) + `comment` (live), each on `PARTICIPATION_ROLE`. `comment`
14
14
  * exists so a suite can create a comment under a post (`root_id !==
15
15
  * parent_id`) and prove the policy resolves from the governing root (the
16
16
  * space), not the immediate parent. Shared by the gated-create and moderate
17
- * cross suites.
17
+ * cross suites, which pass it as a root's `cell_create` `policy`.
18
18
  */
19
19
  export declare const TEST_SPACE_POLICY: {
20
- readonly policy: {
21
- readonly post: {
22
- readonly min_role: "participant";
23
- readonly moderation_required: true;
24
- };
25
- readonly react: {
26
- readonly min_role: "participant";
27
- readonly moderation_required: false;
28
- };
29
- readonly comment: {
30
- readonly min_role: "participant";
31
- readonly moderation_required: false;
32
- };
20
+ readonly post: {
21
+ readonly min_role: "participant";
22
+ readonly moderation_required: true;
23
+ };
24
+ readonly react: {
25
+ readonly min_role: "participant";
26
+ readonly moderation_required: false;
27
+ };
28
+ readonly comment: {
29
+ readonly min_role: "participant";
30
+ readonly moderation_required: false;
33
31
  };
34
32
  };
35
- /** A space's per-kind contribution rule (the shape stamped into `space.data.policy`). */
33
+ /** A space's per-kind contribution rule (the shape of each `policy` entry). */
36
34
  export interface ContributionRule {
37
35
  min_role?: string;
38
36
  moderation_required?: boolean;
39
37
  }
40
38
  /**
41
- * The directory-model test authorizer — a **pure** function of the input (it
42
- * reads the governing root's policy off `input.root_data`, supplied by the
43
- * handler). Byte-equivalent with the Rust `TestCellGatedCreateAuthorize`.
39
+ * The directory-model test authorizer — `authorize` is a **pure** function of
40
+ * the input (it reads the governing root's policy off `input.root_policy`,
41
+ * supplied by the handler). Byte-equivalent with the Rust
42
+ * `TestCellGatedCreateAuthorize`.
44
43
  */
45
44
  export declare const test_cell_gated_create_authorize: CellCreateAuthorize;
46
45
  //# sourceMappingURL=test_cell_gated_create_authorize.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"test_cell_gated_create_authorize.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/test_cell_gated_create_authorize.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AA4B9B,OAAO,KAAK,EACX,mBAAmB,EAGnB,MAAM,4BAA4B,CAAC;AAGpC,8EAA8E;AAC9E,eAAO,MAAM,eAAe,UAAU,CAAC;AAEvC;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,gBAAyB,CAAC;AAEzD;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;CAMpB,CAAC;AAEX,yFAAyF;AACzF,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAYD;;;;GAIG;AACH,eAAO,MAAM,gCAAgC,EAAE,mBAsB9C,CAAC"}
1
+ {"version":3,"file":"test_cell_gated_create_authorize.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/test_cell_gated_create_authorize.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAiC9B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAKtE,8EAA8E;AAC9E,eAAO,MAAM,eAAe,UAAU,CAAC;AAEvC;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,gBAAyB,CAAC;AAEzD;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;CAIpB,CAAC;AAEX,+EAA+E;AAC/E,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAwBD;;;;;GAKG;AACH,eAAO,MAAM,gCAAgC,EAAE,mBA8B9C,CAAC"}