@fuzdev/fuz_app 0.111.0 → 0.113.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 (212) hide show
  1. package/dist/actions/CLAUDE.md +15 -11
  2. package/dist/actions/action_rpc.d.ts +1 -1
  3. package/dist/actions/action_rpc.d.ts.map +1 -1
  4. package/dist/actions/action_rpc.js +4 -6
  5. package/dist/actions/peer_ping.d.ts +8 -0
  6. package/dist/actions/peer_ping.d.ts.map +1 -1
  7. package/dist/actions/peer_ping.js +8 -0
  8. package/dist/actions/peer_request.d.ts +1 -1
  9. package/dist/actions/peer_request.js +1 -1
  10. package/dist/actions/perform_action.d.ts +16 -9
  11. package/dist/actions/perform_action.d.ts.map +1 -1
  12. package/dist/actions/perform_action.js +30 -21
  13. package/dist/actions/register_action_ws.d.ts +1 -1
  14. package/dist/actions/register_action_ws.d.ts.map +1 -1
  15. package/dist/actions/register_action_ws.js +88 -21
  16. package/dist/auth/CLAUDE.md +43 -8
  17. package/dist/auth/account_actions.d.ts.map +1 -1
  18. package/dist/auth/account_actions.js +10 -1
  19. package/dist/auth/account_queries.d.ts.map +1 -1
  20. package/dist/auth/account_queries.js +36 -16
  21. package/dist/auth/account_schema.d.ts +20 -0
  22. package/dist/auth/account_schema.d.ts.map +1 -1
  23. package/dist/auth/account_schema.js +22 -1
  24. package/dist/auth/actor_search_actions.d.ts +3 -3
  25. package/dist/auth/actor_search_actions.d.ts.map +1 -1
  26. package/dist/auth/actor_search_actions.js +10 -6
  27. package/dist/auth/api_token_queries.d.ts.map +1 -1
  28. package/dist/auth/api_token_queries.js +11 -5
  29. package/dist/auth/app_settings_queries.d.ts.map +1 -1
  30. package/dist/auth/app_settings_queries.js +6 -4
  31. package/dist/auth/audit_log_queries.d.ts +6 -0
  32. package/dist/auth/audit_log_queries.d.ts.map +1 -1
  33. package/dist/auth/audit_log_queries.js +11 -5
  34. package/dist/auth/audit_log_route_schema.d.ts.map +1 -1
  35. package/dist/auth/audit_log_route_schema.js +12 -1
  36. package/dist/auth/cell_actions.d.ts.map +1 -1
  37. package/dist/auth/cell_actions.js +3 -8
  38. package/dist/auth/cell_audit_actions.d.ts.map +1 -1
  39. package/dist/auth/cell_audit_actions.js +1 -1
  40. package/dist/auth/cell_field_actions.js +1 -1
  41. package/dist/auth/cell_grant_actions.js +1 -1
  42. package/dist/auth/cell_item_actions.js +1 -1
  43. package/dist/auth/invite_queries.d.ts.map +1 -1
  44. package/dist/auth/invite_queries.js +10 -8
  45. package/dist/auth/role_grant_offer_action_specs.d.ts +2 -1
  46. package/dist/auth/role_grant_offer_action_specs.d.ts.map +1 -1
  47. package/dist/auth/role_grant_offer_action_specs.js +2 -1
  48. package/dist/auth/role_grant_offer_ddl.d.ts +11 -0
  49. package/dist/auth/role_grant_offer_ddl.d.ts.map +1 -1
  50. package/dist/auth/role_grant_offer_ddl.js +20 -2
  51. package/dist/auth/role_grant_offer_queries.d.ts.map +1 -1
  52. package/dist/auth/role_grant_offer_queries.js +29 -15
  53. package/dist/auth/role_grant_queries.d.ts.map +1 -1
  54. package/dist/auth/role_grant_queries.js +21 -7
  55. package/dist/auth/session_queries.d.ts.map +1 -1
  56. package/dist/auth/session_queries.js +9 -4
  57. package/dist/db/CLAUDE.md +21 -2
  58. package/dist/db/cell_audit_queries.js +2 -2
  59. package/dist/db/cell_field_queries.d.ts +1 -1
  60. package/dist/db/cell_field_queries.d.ts.map +1 -1
  61. package/dist/db/cell_field_queries.js +8 -6
  62. package/dist/db/cell_grant_queries.d.ts +1 -1
  63. package/dist/db/cell_grant_queries.d.ts.map +1 -1
  64. package/dist/db/cell_grant_queries.js +12 -10
  65. package/dist/db/cell_item_queries.d.ts +1 -1
  66. package/dist/db/cell_item_queries.d.ts.map +1 -1
  67. package/dist/db/cell_item_queries.js +9 -7
  68. package/dist/db/cell_queries.d.ts +3 -3
  69. package/dist/db/cell_queries.d.ts.map +1 -1
  70. package/dist/db/cell_queries.js +6 -4
  71. package/dist/db/fact_disk_storage.js +1 -1
  72. package/dist/db/fact_queries.d.ts.map +1 -1
  73. package/dist/db/fact_queries.js +9 -3
  74. package/dist/db/sql_columns.d.ts +80 -3
  75. package/dist/db/sql_columns.d.ts.map +1 -1
  76. package/dist/db/sql_columns.js +91 -4
  77. package/dist/http/CLAUDE.md +6 -4
  78. package/dist/http/auth_shape.d.ts +19 -6
  79. package/dist/http/auth_shape.d.ts.map +1 -1
  80. package/dist/http/auth_shape.js +19 -6
  81. package/dist/http/jsonrpc_helpers.d.ts +13 -0
  82. package/dist/http/jsonrpc_helpers.d.ts.map +1 -1
  83. package/dist/http/jsonrpc_helpers.js +13 -0
  84. package/dist/http/surface_query.d.ts +29 -4
  85. package/dist/http/surface_query.d.ts.map +1 -1
  86. package/dist/http/surface_query.js +30 -5
  87. package/dist/realtime/sse_auth_guard.d.ts +9 -3
  88. package/dist/realtime/sse_auth_guard.d.ts.map +1 -1
  89. package/dist/realtime/sse_auth_guard.js +9 -3
  90. package/dist/server/serve_fact_route.d.ts.map +1 -1
  91. package/dist/server/serve_fact_route.js +7 -2
  92. package/dist/testing/CLAUDE.md +54 -28
  93. package/dist/testing/admin_integration.d.ts +0 -3
  94. package/dist/testing/admin_integration.d.ts.map +1 -1
  95. package/dist/testing/admin_integration.js +0 -1
  96. package/dist/testing/adversarial_404.d.ts.map +1 -1
  97. package/dist/testing/adversarial_404.js +4 -1
  98. package/dist/testing/adversarial_input.d.ts.map +1 -1
  99. package/dist/testing/adversarial_input.js +5 -4
  100. package/dist/testing/app_server.d.ts +4 -3
  101. package/dist/testing/app_server.d.ts.map +1 -1
  102. package/dist/testing/app_server.js +11 -5
  103. package/dist/testing/attack_surface.d.ts +21 -2
  104. package/dist/testing/attack_surface.d.ts.map +1 -1
  105. package/dist/testing/attack_surface.js +78 -27
  106. package/dist/testing/audit_completeness.d.ts +0 -3
  107. package/dist/testing/audit_completeness.d.ts.map +1 -1
  108. package/dist/testing/audit_completeness.js +0 -1
  109. package/dist/testing/auth_apps.d.ts +34 -2
  110. package/dist/testing/auth_apps.d.ts.map +1 -1
  111. package/dist/testing/auth_apps.js +43 -7
  112. package/dist/testing/cross_backend/account_lifecycle.d.ts +5 -4
  113. package/dist/testing/cross_backend/account_lifecycle.d.ts.map +1 -1
  114. package/dist/testing/cross_backend/account_lifecycle.js +7 -0
  115. package/dist/testing/cross_backend/action_manifest.d.ts +19 -3
  116. package/dist/testing/cross_backend/action_manifest.d.ts.map +1 -1
  117. package/dist/testing/cross_backend/action_manifest.js +10 -4
  118. package/dist/testing/cross_backend/action_manifest_parity.d.ts +9 -3
  119. package/dist/testing/cross_backend/action_manifest_parity.d.ts.map +1 -1
  120. package/dist/testing/cross_backend/action_manifest_parity.js +6 -0
  121. package/dist/testing/cross_backend/actor_lookup.d.ts +3 -2
  122. package/dist/testing/cross_backend/actor_lookup.d.ts.map +1 -1
  123. package/dist/testing/cross_backend/body_size.d.ts +4 -2
  124. package/dist/testing/cross_backend/body_size.d.ts.map +1 -1
  125. package/dist/testing/cross_backend/body_size.js +1 -1
  126. package/dist/testing/cross_backend/cell_crud.d.ts +2 -2
  127. package/dist/testing/cross_backend/cell_crud.d.ts.map +1 -1
  128. package/dist/testing/cross_backend/cell_crud.js +10 -0
  129. package/dist/testing/cross_backend/cell_gated_create.d.ts +3 -3
  130. package/dist/testing/cross_backend/cell_gated_create.d.ts.map +1 -1
  131. package/dist/testing/cross_backend/cell_grant_role.d.ts +2 -2
  132. package/dist/testing/cross_backend/cell_grant_role.d.ts.map +1 -1
  133. package/dist/testing/cross_backend/cell_relations.d.ts +2 -2
  134. package/dist/testing/cross_backend/cell_relations.d.ts.map +1 -1
  135. package/dist/testing/cross_backend/fact_serving.d.ts +2 -2
  136. package/dist/testing/cross_backend/fact_serving.d.ts.map +1 -1
  137. package/dist/testing/cross_backend/make_cross_backend_project.d.ts +17 -2
  138. package/dist/testing/cross_backend/make_cross_backend_project.d.ts.map +1 -1
  139. package/dist/testing/cross_backend/make_cross_backend_project.js +23 -3
  140. package/dist/testing/cross_backend/origin.d.ts +4 -2
  141. package/dist/testing/cross_backend/origin.d.ts.map +1 -1
  142. package/dist/testing/cross_backend/origin.js +1 -1
  143. package/dist/testing/cross_backend/peer_ping_ws.d.ts.map +1 -1
  144. package/dist/testing/cross_backend/peer_ping_ws.js +11 -7
  145. package/dist/testing/cross_backend/query_shape.d.ts +6 -5
  146. package/dist/testing/cross_backend/query_shape.d.ts.map +1 -1
  147. package/dist/testing/cross_backend/ready.d.ts +2 -2
  148. package/dist/testing/cross_backend/ready.d.ts.map +1 -1
  149. package/dist/testing/cross_backend/role_grant_offer_enumeration.d.ts.map +1 -1
  150. package/dist/testing/cross_backend/role_grant_offer_enumeration.js +7 -1
  151. package/dist/testing/cross_backend/setup.d.ts +26 -6
  152. package/dist/testing/cross_backend/setup.d.ts.map +1 -1
  153. package/dist/testing/cross_backend/standard.d.ts +5 -1
  154. package/dist/testing/cross_backend/standard.d.ts.map +1 -1
  155. package/dist/testing/cross_backend/standard.js +1 -5
  156. package/dist/testing/cross_backend/testing_backdoor.js +1 -1
  157. package/dist/testing/cross_backend/testing_reset_actions.d.ts +5 -0
  158. package/dist/testing/cross_backend/testing_reset_actions.d.ts.map +1 -1
  159. package/dist/testing/cross_backend/testing_reset_actions.js +3 -2
  160. package/dist/testing/cross_backend/token_lifetime.d.ts.map +1 -1
  161. package/dist/testing/cross_backend/token_lifetime.js +6 -0
  162. package/dist/testing/cross_backend/token_scope_surface.d.ts +2 -2
  163. package/dist/testing/cross_backend/token_scope_surface.d.ts.map +1 -1
  164. package/dist/testing/cross_backend/token_scope_surface.js +36 -7
  165. package/dist/testing/cross_backend/wire_shapes.d.ts +22 -0
  166. package/dist/testing/cross_backend/wire_shapes.d.ts.map +1 -0
  167. package/dist/testing/cross_backend/wire_shapes.js +41 -0
  168. package/dist/testing/data_exposure.d.ts +0 -3
  169. package/dist/testing/data_exposure.d.ts.map +1 -1
  170. package/dist/testing/data_exposure.js +0 -1
  171. package/dist/testing/db.d.ts +44 -7
  172. package/dist/testing/db.d.ts.map +1 -1
  173. package/dist/testing/db.js +62 -27
  174. package/dist/testing/integration.d.ts.map +1 -1
  175. package/dist/testing/integration.js +15 -2
  176. package/dist/testing/round_trip.d.ts +0 -3
  177. package/dist/testing/round_trip.d.ts.map +1 -1
  178. package/dist/testing/round_trip.js +0 -4
  179. package/dist/testing/rpc_attack_surface.js +2 -2
  180. package/dist/testing/rpc_round_trip.d.ts +0 -3
  181. package/dist/testing/rpc_round_trip.d.ts.map +1 -1
  182. package/dist/testing/rpc_round_trip.js +0 -1
  183. package/dist/testing/schema_generators.d.ts +15 -0
  184. package/dist/testing/schema_generators.d.ts.map +1 -1
  185. package/dist/testing/schema_generators.js +45 -11
  186. package/dist/testing/standard.d.ts +5 -1
  187. package/dist/testing/standard.d.ts.map +1 -1
  188. package/dist/testing/standard.js +2 -7
  189. package/dist/testing/surface_invariants.d.ts +7 -1
  190. package/dist/testing/surface_invariants.d.ts.map +1 -1
  191. package/dist/testing/surface_invariants.js +11 -5
  192. package/dist/timestamp.d.ts +58 -0
  193. package/dist/timestamp.d.ts.map +1 -0
  194. package/dist/timestamp.js +57 -0
  195. package/dist/ui/AdminAccounts.svelte +6 -4
  196. package/dist/ui/AdminAccounts.svelte.d.ts.map +1 -1
  197. package/dist/ui/AdminInvites.svelte +3 -3
  198. package/dist/ui/AdminInvites.svelte.d.ts.map +1 -1
  199. package/dist/ui/AdminOverview.svelte +10 -10
  200. package/dist/ui/AdminOverview.svelte.d.ts.map +1 -1
  201. package/dist/ui/AdminRoleGrantHistory.svelte +7 -7
  202. package/dist/ui/AdminRoleGrantHistory.svelte.d.ts.map +1 -1
  203. package/dist/ui/AdminSettings.svelte +1 -1
  204. package/dist/ui/RoleGrantOfferHistory.svelte +3 -1
  205. package/dist/ui/RoleGrantOfferHistory.svelte.d.ts.map +1 -1
  206. package/dist/ui/RoleGrantOfferInbox.svelte +4 -1
  207. package/dist/ui/RoleGrantOfferInbox.svelte.d.ts.map +1 -1
  208. package/dist/ui/SurfaceExplorer.svelte +33 -17
  209. package/dist/ui/SurfaceExplorer.svelte.d.ts.map +1 -1
  210. package/dist/ui/role_grant_offers_state.svelte.d.ts.map +1 -1
  211. package/dist/ui/role_grant_offers_state.svelte.js +6 -2
  212. package/package.json +10 -10
@@ -150,11 +150,16 @@ const cell_fact_params_schema = z.strictObject({
150
150
  cell_id: Uuid,
151
151
  hash: FactHashSchema
152
152
  });
153
- /** Shared error-schema entry: tighten the auto-derived 400 to the literal emitted by params validation. */
153
+ /**
154
+ * Shared error-schema entry: tighten the auto-derived 400 to the literal
155
+ * emitted by params validation. `issues` is optional because the framework
156
+ * emits it through `dev_only` — a production body carries the `error`
157
+ * literal alone.
158
+ */
154
159
  const params_400_error = {
155
160
  400: z.looseObject({
156
161
  error: z.literal(ERROR_INVALID_ROUTE_PARAMS),
157
- issues: z.array(z.unknown())
162
+ issues: z.array(z.unknown()).optional()
158
163
  })
159
164
  };
160
165
  /**
@@ -121,7 +121,8 @@ factories accept any migration namespace set.
121
121
  - `IS_CI` — `process.env.CI === 'true'`.
122
122
  - `DbFactory` — `{name, create, close, skip, skip_reason?}`.
123
123
  - `reset_pglite(db)` — `DROP SCHEMA public CASCADE` + recreate. Reuses a live PGlite instance.
124
- - `create_pglite_factory(init_schema)` — in-memory; no external deps; `skip: false`. See WASM caching below.
124
+ - `create_pglite_factory(init_schema, options?)` — in-memory; no external deps; `skip: false`. `options.substitutable: false` pins the call site to PGlite when a substitute is installed. See WASM caching below.
125
+ - `set_substitute_db_factory(create_factory | null)` — install a `DbFactoryBuilder` that stands in for `create_pglite_factory`, so a suite written against PGlite runs on another driver without being edited. Injected rather than selected here: the drivers a substitute wraps live in test-side code this shipped module can't import. fuz_app's own switch is `src/test/db_substitute.ts`.
125
126
  - `create_pg_factory(init_schema, test_url?)` — PostgreSQL; `skip: true` when `test_url` missing. Drops `schema_version` before `init_schema` so migrations re-evaluate against actual tables (prevents stale tracker rows from skipping migrations when DDL changes between sessions). Pool reused + cleaned up across `create()` calls.
126
127
  - `auth_truncate_tables` — `['invite', 'api_token', 'auth_session', 'role_grant', 'role_grant_offer', 'actor', 'account']` in FK-safe order. Excludes `audit_log` — unit DB tests don't need to truncate it.
127
128
  - `auth_integration_truncate_tables` — `auth_truncate_tables + ['audit_log']` for integration suites that exercise the audit path.
@@ -131,14 +132,13 @@ factories accept any migration namespace set.
131
132
  - `assert_columns_match_live(db, table, columns)` — the named-projection drift guard: asserts a `*_COLUMNS` const (`ACCOUNT_COLUMNS`, `CELL_COLUMNS`, a consumer's own) names exactly the live `public`-schema columns of `table`, via `query_public_columns(db, {table})`. Per module, or iterated from a table → const registry (fuz_app's own: `src/test/db/column_projections.db.test.ts`).
132
133
 
133
134
  **PGlite WASM caching.** `create_pglite_factory` shares a single PGlite
134
- instance in a module-level ref (`module_db`) across all factories in the
135
- same vitest worker thread. Subsequent `create()` calls
136
- `DROP SCHEMA public CASCADE` instead of paying the ~500–700ms WASM cold-start
137
- cost again. Each vitest file runs in its own worker, so no cross-file
138
- contamination — but inside a file, suites share state until the schema is
135
+ instance in a module-level ref (`module_db`) across the PGlite factories it builds.
136
+ Subsequent `create()` calls `DROP SCHEMA public CASCADE` instead of paying the
137
+ ~500–700ms WASM cold-start cost again, so suites share state until the next
139
138
  reset. The `db` vitest project (opted into by the `.db.test.ts` suffix) runs
140
139
  with `isolate: false` + `fileParallelism: false` to amortize WASM boot across
141
- every DB test file.
140
+ every DB test file — which also makes that one instance the whole run's; a
141
+ project that isolates its files gets one per worker instead.
142
142
 
143
143
  ## Test app assembly
144
144
 
@@ -207,7 +207,7 @@ test-only by construction.
207
207
  - `AuthTestApps` — `{public, authed, keeper, by_role: Map<string, Hono>}`.
208
208
  - `create_auth_test_apps(specs, roles)` — builds one app per auth level. Keeper app uses `credential_type: 'daemon_token'` so `require_credential_types(['daemon_token'])` passes.
209
209
  - `select_auth_app(apps, auth)` — map `RouteAuth` → matching Hono app. Throws for missing `role:*` entries.
210
- - `resolve_test_path(path)` — `:foo` → `test_foo`; adequate for routes without format-constrained params.
210
+ - `create_route_skip_filter(skip_routes)` — the `'METHOD /path'` skip predicate the three adversarial sub-suites apply from their `skip_routes` option.
211
211
 
212
212
  ## Cross-impl schema parity
213
213
 
@@ -237,8 +237,10 @@ per-method auth shape.
237
237
  - `cross_backend/action_manifest.ts` — `ActionManifest` / `ActionManifestEntry`
238
238
  Zod schema (the `_testing_action_manifest` wire validator) + `build_action_manifest(specs)`,
239
239
  which normalizes each spec to `{method, side_effects, account, actor, roles,
240
- credential_types}` (auth axes pass through; `roles` / `credential_types` flatten
241
- to sorted arrays). Twin of `schema_introspect.ts`. Excludes the protocol actions
240
+ credential_types, rate_limit}` (auth axes pass through; `roles` /
241
+ `credential_types` flatten to sorted arrays; `rate_limit` is the declared
242
+ class or an explicit `null`, so a missing key reads as drift rather than a
243
+ default). Twin of `schema_introspect.ts`. Excludes the protocol actions
242
244
  (`heartbeat` / `cancel` / `peer/ping`) — `create_testing_action_manifest_action`
243
245
  filters them via the `protocol_action_specs` method set (Rust drops
244
246
  `PROTOCOL_ACTION_SPECS`); the two impls organize them differently (`peer/ping`
@@ -247,6 +249,8 @@ credential_types}` (auth axes pass through; `roles` / `credential_types` flatten
247
249
  - `cross_backend/action_manifest_parity.ts` — `diff_action_manifests` /
248
250
  `format_action_manifest_diffs` / `assert_action_manifests_equal` (twin of
249
251
  `schema_parity.ts`) — asserts exact method-set + per-method auth-shape parity.
252
+ `ActionManifestDiff` kinds: `method_only_in`, `side_effects_differ`,
253
+ `rate_limit_differs`, `auth_field_differs`, `auth_list_differs`.
250
254
  - `cross_backend/setup.ts` `capture_action_manifest(handle)` — dumps a backend's
251
255
  manifest over the daemon-token `_testing_action_manifest` channel (twin of
252
256
  `capture_schema_snapshot`).
@@ -255,9 +259,9 @@ It runs under the same dual-spawn `cross_backend_parity` project (one TS-spine +
255
259
  Rust-stub spawn serves both gates). It complements the in-repo
256
260
  `spine_method_coverage` reconciliation gate (which proves _mounted ⟹ covered_);
257
261
  this proves _TS-mount-set ≡ Rust-mount-set_. The gate asserts **exact** parity —
258
- every mounted method and its full auth shape (side-effects + the four auth axes)
259
- must match across the two impls, with no allowlisted divergences (see
260
- `action_manifest_parity.cross.test.ts`).
262
+ every mounted method and its full auth shape (side-effects, the four auth axes,
263
+ the rate-limit class) must match across the two impls, with no allowlisted
264
+ divergences (see `action_manifest_parity.cross.test.ts`).
261
265
 
262
266
  **Cross-impl gate pattern** — a dual-impl consumer running two backends
263
267
  (a TS Hono server and a Rust spine server) against a shared schema, plus
@@ -367,7 +371,7 @@ Walks Zod schemas to generate valid values for adversarial/round-trip tests.
367
371
 
368
372
  - `detect_format(field_schema)` — reads `format` / `pattern` from the JSON Schema representation.
369
373
  - `generate_valid_value(field, field_schema)` — base-type switch producing a valid sample (UUIDs → nil UUID, strings → `'xxxxxxxxxx'`, numbers → `1`, objects → recurse, enums → first entry, etc.). For branded-string refinements, walks a fallback chain synthesized from the `pattern` string the JSON Schema representation exposes: fixed-length hex (`^[0-9a-f]{N}$` — blake3 / sha256 / md5 digests; `0`.repeat(N)), prefix-lengthed slug (`^<prefix>_[A-Za-z0-9_-]{N}$` — `ApiTokenId`-style ids; `<prefix>_` + `x`.repeat(N)), absolute path prefix, URL prefix. First candidate that `safeParse` accepts is used.
370
- - `resolve_valid_path(path, params_schema?)` — swaps `:param` for valid-format values (nil UUID for UUID params, `test_param` otherwise).
374
+ - `resolve_valid_path(path, params_schema?)` — swaps `:param` for a value the params schema accepts. Prefers `test_<name>` wherever the field schema admits it (the param name keeps failure messages readable); otherwise a UUID param takes the nil UUID and anything else is synthesized from the schema, percent-encoded. A synthesized value containing `/` is refused (it would route elsewhere) and falls back to `test_<name>`.
371
375
  - `generate_valid_body(input_schema) => Record<string, unknown> | undefined` — builds a body satisfying the input schema. Throws with Zod `issues` if the generated body fails validation — surfaces broken generation logic with a descriptive error rather than a confusing 400 downstream.
372
376
 
373
377
  ### `integration_helpers.ts` — route lookup + body checks
@@ -394,11 +398,20 @@ case per route):
394
398
 
395
399
  1. **attack surface snapshot** — `matches committed snapshot`, `is deterministic`.
396
400
  2. **attack surface structure** — `only expected public routes`, `full middleware stack on API routes`, `surface invariants`, `rpc/ws surface invariants`, `security policy`, `error schema tightness` (logs counts and asserts against `default_error_schema_tightness` by default; pass an override config or `null` via `error_schema_tightness`).
397
- 3. **adversarial HTTP auth enforcement** — `unauthenticated → 401`, `wrong role → 403` × roles, `authenticated without role → 403`, `keeper routes reject session credential → 403`, `correct auth passes guard`.
401
+ 3. **adversarial HTTP auth enforcement** — `unauthenticated → 401`, `wrong role → 403` × roles, `authenticated without role → 403`, `credential-gated routes reject a disallowed credential → 403`, `correct auth passes guard`. The role blocks cover role routes the session-credentialed role apps reach (a keeper route's channel gate answers first); the credential block probes every `auth.credential_types` route on the first builtin channel its allowlist omits, using `AuthTestApps.by_credential_type` (one keeper-role app per builtin channel; `keeper` is its `daemon_token` entry).
398
402
  4. **adversarial input validation** — delegated to `describe_adversarial_input`.
399
403
  5. **adversarial 404 response validation** — delegated to `describe_adversarial_404`.
400
404
 
401
- Options: `{build: () => AppSurfaceSpec, snapshot_path, expected_public_routes, expected_api_middleware, roles, api_path_prefix?, security_policy?, error_schema_tightness?}`.
405
+ Options: `{build: () => AppSurfaceSpec, snapshot_path, expected_public_routes, expected_api_middleware, roles, api_path_prefix?, security_policy?, error_schema_tightness?, skip_routes?}`.
406
+
407
+ `skip_routes` is a list of `'METHOD /path'` surface keys the three
408
+ adversarial sub-suites drop, forwarded to each of them (it also sits on
409
+ `AdversarialTestOptions` for the standalone `describe_adversarial_auth` /
410
+ `describe_adversarial_input` / `describe_adversarial_404` calls). It is the
411
+ escape hatch for a route that cannot be driven generically at all — a
412
+ handler needing real seeded state, a path segment no schema describes. A
413
+ route whose params merely carry a format needs no entry: `resolve_valid_path`
414
+ synthesizes a segment the route accepts.
402
415
 
403
416
  Also exported: `describe_adversarial_auth(options)` (group 3 on its own) and
404
417
  `build_error_schema_lookup(specs, middleware_specs?)` (pre-built
@@ -480,7 +493,7 @@ For every route spec, fires a valid request with matching auth and validates
480
493
  the response against declared schemas. DB-backed via `create_test_app`.
481
494
  Per-route test (`test.each`) — one line per route in the vitest output.
482
495
 
483
- Options: `{setup_test, surface_source, capabilities, skip_routes?, input_overrides?}`.
496
+ Options: `{setup_test, surface_source, skip_routes?, input_overrides?, success_fixtures?}`.
484
497
  `input_overrides` is a `Map<"METHOD /path", body>` — override generated
485
498
  bodies for routes whose input schema can't round-trip cleanly (e.g. fields
486
499
  that must reference DB state).
@@ -493,7 +506,7 @@ picks them up separately.
493
506
  DB-backed round-trip for RPC: one POST test for all methods, one GET test
494
507
  for `side_effects: false` methods. Successful responses validate against
495
508
  `action.spec.output`; error responses validate as well-formed JSON-RPC error
496
- envelopes. Options: `{setup_test, surface_source, capabilities, session_options, rpc_endpoints, skip_methods?, input_overrides?}`.
509
+ envelopes. Options: `{setup_test, surface_source, session_options, rpc_endpoints, skip_methods?, input_overrides?, success_fixtures?}`.
497
510
  The admin RPC auth test picks a session-based identity (`authed` / `admin` /
498
511
  bootstrapped keeper) based on `method.auth`; keeper uses the daemon token.
499
512
 
@@ -568,7 +581,7 @@ Support functions: `collect_json_schema_property_names(schema)` (walks
568
581
  `assert_output_schemas_no_sensitive_fields(surface, fields?)`,
569
582
  `assert_non_admin_schemas_no_admin_fields(surface, fields?)`.
570
583
 
571
- Options: `{setup_test, surface_source, capabilities, sensitive_fields?, admin_only_fields?, skip_routes?}`.
584
+ Options: `{setup_test, surface_source, sensitive_fields?, admin_only_fields?, skip_routes?}`.
572
585
 
573
586
  ### `rate_limiting.ts` — `describe_rate_limiting_tests`
574
587
 
@@ -626,7 +639,7 @@ Override with
626
639
  minimal route sets whose declared error codes outpace the suite's
627
640
  denial-path drivers).
628
641
 
629
- Options: `{setup_test, surface_source, capabilities, session_options, rpc_endpoints, error_coverage_min?}`.
642
+ Options: `{setup_test, surface_source, session_options, rpc_endpoints, error_coverage_min?}`.
630
643
 
631
644
  ### `admin_integration.ts` — `describe_standard_admin_integration_tests`
632
645
 
@@ -646,7 +659,7 @@ header/account mismatch. Direct-grant fixtures (test focuses on revoke or
646
659
  isolation, not the consent path) go through `create_test_role_grant_direct`
647
660
  from `db_entities.ts`.
648
661
 
649
- Required options: `{setup_test, surface_source, capabilities, session_options, rpc_endpoints: RpcEndpointsSuiteOption, roles: RoleSchemaResult, admin_prefix?}`.
662
+ Required options: `{setup_test, surface_source, session_options, rpc_endpoints: RpcEndpointsSuiteOption, roles: RoleSchemaResult, admin_prefix?}`.
650
663
 
651
664
  `rpc_endpoints` is `Array<RpcEndpointSpec> | ((ctx: AppServerContext) => Array<RpcEndpointSpec>)` —
652
665
  the same `RpcEndpointsSuiteOption` union every DB-backed suite accepts
@@ -1179,10 +1192,23 @@ never sees them). Both parse every success response against the verb's Zod
1179
1192
  **output** schema, so a TS↔Rust envelope drift fails the suite — not just a
1180
1193
  payload-field drift. Call-site primitives (`cross_rpc_call` / `error_reason` /
1181
1194
  `expect_output`) live in `cross_backend/cell_cross_helpers.ts`; the shared
1182
- options shape is `RpcPathCrossSuiteOptions` from `cross_backend/setup.ts` (the
1183
- neutral base every RPC-dispatched imperative cross suite aliases — origin,
1184
- body-size, actor lookup/search, account lifecycle, app settings, testing
1185
- backdoor, cell).
1195
+ options shape is `RpcPathCapabilityGatedCrossSuiteOptions` from
1196
+ `cross_backend/setup.ts`. `cross_backend/wire_shapes.ts` carries
1197
+ `assert_iso8601_seconds` / `assert_iso8601_seconds_nullable` — the byte-level
1198
+ gate on the canonical second-precision UTC timestamp shape, which a
1199
+ `z.string()` output schema can't catch (a millisecond stamp parses fine).
1200
+ The shared suites pin it on the account-status account + role grants, a
1201
+ session, a minted + listed API token, a cell's `created_at` / `updated_at`,
1202
+ an audit row, an admin account listing, and an offer's `created_at` /
1203
+ `expires_at`. `cross_backend/setup.ts` carries the four bases every
1204
+ imperative cross suite aliases: `CrossSuiteOptions` (`setup_test` alone),
1205
+ `CapabilityGatedCrossSuiteOptions` (+ `capabilities` — `ready`),
1206
+ `RpcPathCrossSuiteOptions` (+ `rpc_path?` — origin, body-size, actor
1207
+ lookup/search, app settings, testing backdoor), and the intersection
1208
+ `RpcPathCapabilityGatedCrossSuiteOptions` (every `cell_*` suite, query-shape,
1209
+ token-scope surface, fact-serving, account lifecycle). A suite takes the
1210
+ capability-carrying variant only when it actually gates cases on a flag, so
1211
+ the option type states whether the bundle is read.
1186
1212
 
1187
1213
  - **`describe_cell_crud_cross_tests`** (gates on `capabilities.cell_crud`) —
1188
1214
  the create → get → update → delete → list lifecycle threading the id, plus
@@ -1387,7 +1413,7 @@ censuses). Cross-process only; fuz_app's own wiring is
1387
1413
 
1388
1414
  ### Origin verification parity — `cross_backend/origin.ts`
1389
1415
 
1390
- `describe_origin_cross_tests({setup_test, capabilities, rpc_path?})` — the
1416
+ `describe_origin_cross_tests({setup_test, rpc_path?})` — the
1391
1417
  imperative Origin-verification suite: disallowed `Origin` → 403 `forbidden_origin` (refused
1392
1418
  before dispatch), absent `Origin` → request passes (non-browser direct access).
1393
1419
  Imperative (not a conformance-table row) because origin rejection is
@@ -1461,7 +1487,7 @@ drift-guarded by `src/test/cross_backend/spine_expected_schema.db.test.ts`
1461
1487
 
1462
1488
  ### Testing-backdoor credential gate — `cross_backend/testing_backdoor.ts`
1463
1489
 
1464
- `describe_testing_backdoor_cross_tests({setup_test, capabilities, rpc_path?})` —
1490
+ `describe_testing_backdoor_cross_tests({setup_test, rpc_path?})` —
1465
1491
  the negative-credential parity suite for the `_testing_*` backdoor actions.
1466
1492
  For each of `_testing_reset` / `_testing_mint_session` / `_testing_put_fact` /
1467
1493
  `_testing_schema_snapshot` (the three privileged writes plus the schema-dump
@@ -1471,7 +1497,7 @@ proving the daemon-token gate that fences each backdoor action holds end-to-end
1471
1497
  on the real dispatcher (the spec-derived `describe_rpc_attack_surface_tests`
1472
1498
  never enumerates them because they're off the declared surface). Each method is
1473
1499
  sent with **valid** params so each case varies only the credential (validation
1474
- runs after the gates — order is 401 → authz → 403 → 400); the handler never
1500
+ runs after the gates — order is 401 → authz → 403 → 429 → 400); the handler never
1475
1501
  runs. Cited property: `docs/security.md`
1476
1502
  §Test Backdoor Actions. Cross-process only (the `_testing_*` actions are
1477
1503
  mounted on the spawned binary, not the in-process app — like the ws/sse
@@ -3,7 +3,6 @@ import type { SessionOptions } from '../auth/session_cookie.js';
3
3
  import { type RoleSchemaResult } from '../auth/role_schema.js';
4
4
  import { type RpcEndpointsSuiteOption } from './rpc_helpers.js';
5
5
  import type { AppSurfaceSpec } from '../http/surface.js';
6
- import type { BackendCapabilities } from './cross_backend/capabilities.js';
7
6
  import type { SetupTest } from './cross_backend/setup.js';
8
7
  /**
9
8
  * Configuration for `describe_standard_admin_integration_tests`.
@@ -21,8 +20,6 @@ export interface StandardAdminIntegrationTestOptions {
21
20
  * shape for in-process and cross-process tests).
22
21
  */
23
22
  surface_source: AppSurfaceSpec;
24
- /** Backend capability declarations. */
25
- capabilities: BackendCapabilities;
26
23
  /** Session config — needed for cookie_name + factory-form rpc_endpoints resolution. */
27
24
  session_options: SessionOptions<string>;
28
25
  /** Role schema result from `create_role_schema()` — used to determine valid/invalid/web-grantable roles. */
@@ -1 +1 @@
1
- {"version":3,"file":"admin_integration.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/admin_integration.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAgC7B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAc,KAAK,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAW3E,OAAO,EAKN,KAAK,uBAAuB,EAC5B,MAAM,kBAAkB,CAAC;AAmB1B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAC3E,OAAO,KAAK,EAAE,SAAS,EAAe,MAAM,0BAA0B,CAAC;AAYvE;;GAEG;AACH,MAAM,WAAW,mCAAmC;IACnD;;;;OAIG;IACH,UAAU,EAAE,SAAS,CAAC;IACtB;;;;OAIG;IACH,cAAc,EAAE,cAAc,CAAC;IAC/B,uCAAuC;IACvC,YAAY,EAAE,mBAAmB,CAAC;IAClC,uFAAuF;IACvF,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,4GAA4G;IAC5G,KAAK,EAAE,gBAAgB,CAAC;IACxB;;;OAGG;IACH,aAAa,EAAE,uBAAuB,CAAC;IACvC;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAiBD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,yCAAyC,GACrD,SAAS,mCAAmC,KAC1C,IAm5BF,CAAC"}
1
+ {"version":3,"file":"admin_integration.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/admin_integration.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAgC7B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAc,KAAK,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAW3E,OAAO,EAKN,KAAK,uBAAuB,EAC5B,MAAM,kBAAkB,CAAC;AAmB1B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,SAAS,EAAe,MAAM,0BAA0B,CAAC;AAYvE;;GAEG;AACH,MAAM,WAAW,mCAAmC;IACnD;;;;OAIG;IACH,UAAU,EAAE,SAAS,CAAC;IACtB;;;;OAIG;IACH,cAAc,EAAE,cAAc,CAAC;IAC/B,uFAAuF;IACvF,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,4GAA4G;IAC5G,KAAK,EAAE,gBAAgB,CAAC;IACxB;;;OAGG;IACH,aAAa,EAAE,uBAAuB,CAAC;IACvC;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAiBD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,yCAAyC,GACrD,SAAS,mCAAmC,KAC1C,IAk5BF,CAAC"}
@@ -77,7 +77,6 @@ export const describe_standard_admin_integration_tests = (options) => {
77
77
  // confusing test failure when `rpc_endpoints` is missing.
78
78
  const rpc_endpoints_for_setup = resolve_rpc_endpoints_for_setup(options.rpc_endpoints, options.session_options);
79
79
  const rpc_path = require_rpc_endpoint_path(rpc_endpoints_for_setup);
80
- void options.capabilities;
81
80
  describe('standard_admin_integration', () => {
82
81
  const { cookie_name } = options.session_options;
83
82
  const { role_specs } = options.roles;
@@ -1 +1 @@
1
- {"version":3,"file":"adversarial_404.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/adversarial_404.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAoB7B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAyBlE;;;;;;;;GAQG;AACH,eAAO,MAAM,wBAAwB,GAAI,SAAS,sBAAsB,KAAG,IA2E1E,CAAC"}
1
+ {"version":3,"file":"adversarial_404.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/adversarial_404.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAoB7B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAyBlE;;;;;;;;GAQG;AACH,eAAO,MAAM,wBAAwB,GAAI,SAAS,sBAAsB,KAAG,IA6E1E,CAAC"}
@@ -13,7 +13,7 @@ import './assert_dev_env.js';
13
13
  import { test, assert, describe } from 'vitest';
14
14
  import { z } from 'zod';
15
15
  import { is_null_schema } from '../http/schema_helpers.js';
16
- import { create_auth_test_apps, select_auth_app } from './auth_apps.js';
16
+ import { create_auth_test_apps, create_route_skip_filter, select_auth_app } from './auth_apps.js';
17
17
  import { resolve_valid_path, generate_valid_body } from './schema_generators.js';
18
18
  /**
19
19
  * Extract the error code from a 404 Zod schema for use in the stub handler.
@@ -51,6 +51,7 @@ const extract_404_error_code = (schema) => {
51
51
  export const describe_adversarial_404 = (options) => {
52
52
  const { build, roles } = options;
53
53
  const { surface, route_specs } = build();
54
+ const is_skipped = create_route_skip_filter(options.skip_routes);
54
55
  // Build spec lookup for Zod schema access
55
56
  const spec_lookup = new Map();
56
57
  for (const spec of route_specs) {
@@ -63,6 +64,8 @@ export const describe_adversarial_404 = (options) => {
63
64
  continue;
64
65
  if (!route.error_schemas || !('404' in route.error_schemas))
65
66
  continue;
67
+ if (is_skipped(route))
68
+ continue;
66
69
  const key = `${route.method} ${route.path}`;
67
70
  const spec = spec_lookup.get(key);
68
71
  if (!spec?.params || !spec.errors?.[404])
@@ -1 +1 @@
1
- {"version":3,"file":"adversarial_input.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/adversarial_input.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAiB7B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAUxB,OAAO,EAEN,0BAA0B,EAC1B,uBAAuB,EAGvB,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AA8ClE,UAAU,aAAa;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;IACd,cAAc,EAAE,OAAO,0BAA0B,GAAG,OAAO,uBAAuB,CAAC;CACnF;AAED,UAAU,cAAc;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B;AAED,UAAU,aAAa;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AAID;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,yBAAyB,GAAI,cAAc,CAAC,CAAC,OAAO,KAAG,KAAK,CAAC,aAAa,CAsMtF,CAAC;AAIF;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,GAAI,eAAe,CAAC,CAAC,SAAS,KAAG,KAAK,CAAC,cAAc,CA+B3F,CAAC;AAIF;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB,GAAI,cAAc,CAAC,CAAC,SAAS,KAAG,KAAK,CAAC,aAAa,CA4CxF,CAAC;AAqBF;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,GAAI,SAAS,sBAAsB,KAAG,IAkN5E,CAAC"}
1
+ {"version":3,"file":"adversarial_input.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/adversarial_input.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAiB7B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAUxB,OAAO,EAEN,0BAA0B,EAC1B,uBAAuB,EAGvB,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AA8ClE,UAAU,aAAa;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;IACd,cAAc,EAAE,OAAO,0BAA0B,GAAG,OAAO,uBAAuB,CAAC;CACnF;AAED,UAAU,cAAc;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B;AAED,UAAU,aAAa;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AAID;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,yBAAyB,GAAI,cAAc,CAAC,CAAC,OAAO,KAAG,KAAK,CAAC,aAAa,CAsMtF,CAAC;AAIF;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,GAAI,eAAe,CAAC,CAAC,SAAS,KAAG,KAAK,CAAC,cAAc,CA+B3F,CAAC;AAIF;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB,GAAI,cAAc,CAAC,CAAC,SAAS,KAAG,KAAK,CAAC,aAAa,CA4CxF,CAAC;AAqBF;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,GAAI,SAAS,sBAAsB,KAAG,IAmN5E,CAAC"}
@@ -18,7 +18,7 @@ import { zod_unwrap_to_object, zod_extract_fields } from '@fuzdev/fuz_util/zod.t
18
18
  import { is_null_schema } from '../http/schema_helpers.js';
19
19
  import { filter_routes_with_input, filter_routes_with_params, filter_routes_with_query } from '../http/surface_query.js';
20
20
  import { ValidationError, ERROR_INVALID_REQUEST_BODY, ERROR_INVALID_JSON_BODY, ERROR_INVALID_ROUTE_PARAMS, ERROR_INVALID_QUERY_PARAMS } from '../http/error_schemas.js';
21
- import { create_auth_test_apps, select_auth_app } from './auth_apps.js';
21
+ import { create_auth_test_apps, create_route_skip_filter, select_auth_app } from './auth_apps.js';
22
22
  import { detect_format, generate_valid_value, resolve_valid_path } from './schema_generators.js';
23
23
  // --- Payload generation ---
24
24
  /** One wrong-type value per base type — one representative is sufficient. */
@@ -374,9 +374,10 @@ const build_query_url = (path, query) => {
374
374
  export const describe_adversarial_input = (options) => {
375
375
  const { build, roles } = options;
376
376
  const { surface, route_specs } = build();
377
- const routes_with_input = filter_routes_with_input(surface);
378
- const routes_with_params = filter_routes_with_params(surface);
379
- const routes_with_query = filter_routes_with_query(surface);
377
+ const is_skipped = create_route_skip_filter(options.skip_routes);
378
+ const routes_with_input = filter_routes_with_input(surface).filter((r) => !is_skipped(r));
379
+ const routes_with_params = filter_routes_with_params(surface).filter((r) => !is_skipped(r));
380
+ const routes_with_query = filter_routes_with_query(surface).filter((r) => !is_skipped(r));
380
381
  if (routes_with_input.length === 0 &&
381
382
  routes_with_params.length === 0 &&
382
383
  routes_with_query.length === 0)
@@ -3,8 +3,9 @@ import './assert_dev_env.js';
3
3
  * Bootstrapped app server factory for integration tests.
4
4
  *
5
5
  * Creates a keeper account, API token, and signed session cookie on a
6
- * database. By default uses a cached in-memory PGlite (shared WASM instance
7
- * per vitest worker thread via `test_db.ts` module cache); pass `db` to use
6
+ * database. By default uses a cached in-memory PGlite (one shared WASM instance
7
+ * per loaded copy of `testing/db.ts` — once per run under the `db` project's
8
+ * `isolate: false` + `fileParallelism: false`); pass `db` to use
8
9
  * an existing database (any driver) instead.
9
10
  *
10
11
  * Also provides `create_test_app` — a combined helper that creates both
@@ -312,7 +313,7 @@ export interface TestApp {
312
313
  *
313
314
  * A fresh Hono app is created each call — middleware closures bind to the
314
315
  * server's deps (db, keyring), so reuse across servers is unsafe.
315
- * The expensive resource (PGlite WASM) is cached separately in `test_db.ts`.
316
+ * The expensive resource (PGlite WASM) is cached separately in `testing/db.ts`.
316
317
  *
317
318
  * @param options - test app configuration
318
319
  * @returns a `TestApp` ready for HTTP testing
@@ -1 +1 @@
1
- {"version":3,"file":"app_server.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/app_server.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAE7B;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAGjC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAInD,OAAO,EAA4B,KAAK,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE5E,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAU5D,OAAO,EAA+B,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC7F,OAAO,EAAkB,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAE3E,OAAO,EAEN,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAEN,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,EAC3B,KAAK,oBAAoB,EACzB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAOvD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAGhE;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,EAAE,gBAIhC,CAAC;AAEF,gFAAgF;AAChF,eAAO,MAAM,kBAAkB,QAAiB,CAAC;AA0CjD;;;;;GAKG;AACH,MAAM,WAAW,uCAAuC;IACvD,EAAE,EAAE,EAAE,CAAC;IACP,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACtB,+FAA+F;IAC/F,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,2DAA2D;AAC3D,MAAM,MAAM,0BAA0B,GAAG,uCAAuC,CAAC;AAEjF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,oCAAoC,GAChD,SAAS,uCAAuC,KAC9C,OAAO,CAAC;IACV,OAAO,EAAE;QAAE,EAAE,EAAE,IAAI,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IACxC,KAAK,EAAE;QAAE,EAAE,EAAE,IAAI,CAAA;KAAE,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;CACvB,CAqDA,CAAC;AAEF,uCAAuC;AACvC,MAAM,WAAW,sBAAsB;IACtC,EAAE,EAAE,EAAE,CAAC;IACP,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,6CAA6C;IAC7C,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;;;;;OASG;IACH,kBAAkB,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,iBAAiB,GAC7B,SAAS,sBAAsB,KAC7B,OAAO,CAAC;IAAE,cAAc,EAAE,MAAM,CAAA;CAAE,CAQpC,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,qBAAqB,GACjC,SAAS,0BAA0B,KACjC,OAAO,CAAC;IACV,OAAO,EAAE;QAAE,EAAE,EAAE,IAAI,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IACxC,KAAK,EAAE;QAAE,EAAE,EAAE,IAAI,CAAA;KAAE,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;CACvB,CAQA,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,aAAc,SAAQ,UAAU;IAChD,gCAAgC;IAChC,OAAO,EAAE;QAAE,EAAE,EAAE,IAAI,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IACxC,uCAAuC;IACvC,KAAK,EAAE;QAAE,EAAE,EAAE,IAAI,CAAA;KAAE,CAAC;IACpB,qCAAqC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,cAAc,EAAE,MAAM,CAAC;IACvB,+FAA+F;IAC/F,OAAO,EAAE,OAAO,CAAC;IACjB,4EAA4E;IAC5E,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACpC,mDAAmD;IACnD,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,kGAAkG;IAClG,EAAE,CAAC,EAAE,EAAE,CAAC;IACR,0FAA0F;IAC1F,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;;;;OASG;IACH,oBAAoB,CAAC,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC;IACzD,yHAAyH;IACzH,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+EAA+E;IAC/E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gDAAgD;IAChD,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACtB;;;;;;;;;;;;;;OAcG;IACH,aAAa,CAAC,EAAE,YAAY,CAAC;CAC7B;AA0ID,eAAO,MAAM,sBAAsB,GAClC,SAAS,oBAAoB,KAC3B,OAAO,CAAC,aAAa,CA2BvB,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,oBAAqB,SAAQ,oBAAoB;IACjE,yEAAyE;IACzE,kBAAkB,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;IACpE;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,uBAAuB,CAAC;IACxC;;;;;;;;;;;OAWG;IACH,SAAS,CAAC,EAAE,sBAAsB,CAAC;IACnC;;;;;OAKG;IACH,WAAW,CAAC,EAAE,eAAe,CAAC;CAC9B;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,eAAe,GAAG,OAAO,CACpC,IAAI,CACH,gBAAgB,EAChB,SAAS,GAAG,iBAAiB,GAAG,oBAAoB,GAAG,eAAe,GAAG,WAAW,CACpF,CACD,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,WAAW;IAC3B,OAAO,EAAE;QAAE,EAAE,EAAE,IAAI,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IACxC,KAAK,EAAE;QAAE,EAAE,EAAE,IAAI,CAAA;KAAE,CAAC;IACpB,mCAAmC;IACnC,cAAc,EAAE,MAAM,CAAC;IACvB,qCAAqC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,gEAAgE;IAChE,sBAAsB,EAAE,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnF,8DAA8D;IAC9D,qBAAqB,EAAE,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClF;AAED;;;;;GAKG;AACH,MAAM,WAAW,wBAAwB;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACtB,+FAA+F;IAC/F,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,OAAO;IACvB,GAAG,EAAE,IAAI,CAAC;IACV,OAAO,EAAE,aAAa,CAAC;IACvB,YAAY,EAAE,cAAc,CAAC;IAC7B,OAAO,EAAE,UAAU,CAAC;IACpB,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAC9B,kEAAkE;IAClE,sBAAsB,EAAE,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnF,gEAAgE;IAChE,qBAAqB,EAAE,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClF,iEAAiE;IACjE,2BAA2B,EAAE,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxF,qDAAqD;IACrD,cAAc,EAAE,CAAC,OAAO,CAAC,EAAE,wBAAwB,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;IAC7E,8DAA8D;IAC9D,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7B;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,eAAe,GAAU,SAAS,oBAAoB,KAAG,OAAO,CAAC,OAAO,CAoGpF,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,WAAW,gCAAgC;IAChD,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,kBAAkB,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;IACpE,aAAa,CAAC,EAAE,uBAAuB,CAAC;IACxC,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,8EAA8E;IAC9E,SAAS,EAAE,oBAAoB,CAAC;IAChC;;;;OAIG;IACH,eAAe,EAAE,MAAM,CAAC;IACxB,EAAE,CAAC,EAAE,EAAE,CAAC;IACR,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,aAAa,CAAC,EAAE,YAAY,CAAC;CAC7B;AAED;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IACnC,GAAG,EAAE,IAAI,CAAC;IACV,OAAO,EAAE,UAAU,CAAC;IACpB,YAAY,EAAE,cAAc,CAAC;IAC7B,OAAO,EAAE,UAAU,CAAC;IACpB,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAC9B,0EAA0E;IAC1E,sBAAsB,EAAE,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnF,4EAA4E;IAC5E,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,6BAA6B,GACzC,SAAS,gCAAgC,KACvC,OAAO,CAAC,mBAAmB,CA0E7B,CAAC"}
1
+ {"version":3,"file":"app_server.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/app_server.ts"],"names":[],"mappings":"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"}
@@ -31,8 +31,8 @@ export const stub_password_deps = {
31
31
  /** 64-hex-char test cookie secret — deterministic, never used in production. */
32
32
  export const TEST_COOKIE_SECRET = 'a'.repeat(64);
33
33
  // Module-level PGlite factory for create_test_app_server when no db is provided.
34
- // Shares the WASM instance cache from test_db.ts, avoiding redundant cold starts
35
- // within the same vitest worker thread. Schema is reset on each create() call.
34
+ // Shares the WASM instance cache from `testing/db.ts`, avoiding redundant cold starts
35
+ // within one loaded copy of that module. Schema is reset on each create() call.
36
36
  const fallback_pglite_factory = create_pglite_factory(async (db) => {
37
37
  await run_migrations(db, [auth_migration_ns]);
38
38
  });
@@ -205,10 +205,16 @@ const _build_test_backend = async (options) => {
205
205
  };
206
206
  }
207
207
  else {
208
- // In-memory PGlite via cached factory — reuses the WASM instance from test_db.ts
208
+ // In-memory PGlite via cached factory — reuses the WASM instance from `testing/db.ts`
209
209
  // instead of creating a new PGlite each time. Schema is reset and migrations re-run
210
- // on each call, but the expensive WASM cold start only happens once per worker thread.
210
+ // on each call, but the expensive WASM cold start only happens once per loaded
211
+ // copy of `testing/db.ts` — under the `db` project's `isolate: false` +
212
+ // `fileParallelism: false` that is once for the whole run.
211
213
  // `migration_namespaces` selects an auth+extras factory; auth-only is the default.
214
+ // `db_type` below names PGlite unconditionally: a run that installs a substitute
215
+ // factory (`set_substitute_db_factory`) before this module loads gets that driver
216
+ // here, and no caller reads this field to pick behavior — it is reported, not
217
+ // dispatched on.
212
218
  const db = await resolve_fallback_factory(migration_namespaces).create();
213
219
  const audit = audit_factory({ db, log: test_log });
214
220
  backend = {
@@ -255,7 +261,7 @@ export const create_test_app_server = async (options) => {
255
261
  *
256
262
  * A fresh Hono app is created each call — middleware closures bind to the
257
263
  * server's deps (db, keyring), so reuse across servers is unsafe.
258
- * The expensive resource (PGlite WASM) is cached separately in `test_db.ts`.
264
+ * The expensive resource (PGlite WASM) is cached separately in `testing/db.ts`.
259
265
  *
260
266
  * @param options - test app configuration
261
267
  * @returns a `TestApp` ready for HTTP testing
@@ -7,14 +7,25 @@ export interface AdversarialTestOptions {
7
7
  build: () => AppSurfaceSpec;
8
8
  /** All roles in the app (e.g. `['admin', 'keeper']`). */
9
9
  roles: Array<string>;
10
+ /**
11
+ * Routes to skip, in `'METHOD /path'` form (the surface key) — the escape
12
+ * hatch every sibling suite carries. Reach for it only when a route
13
+ * cannot be driven generically at all (a handler needing real seeded
14
+ * state, a path segment no schema can describe); a route whose params
15
+ * merely have a format is handled by the synthesizer.
16
+ */
17
+ skip_routes?: Array<string>;
10
18
  }
11
19
  /**
12
20
  * Generate adversarial HTTP auth enforcement test suites.
13
21
  *
14
22
  * Describe blocks:
15
23
  * - unauthenticated → 401 — every protected route
16
- * - wrong role → 403 — every role route, tested with all non-matching roles
17
- * - authenticated without role → 403 — every role route, no-role context
24
+ * - wrong role → 403 — every role route the role apps' session credential
25
+ * reaches, tested with all non-matching roles
26
+ * - authenticated without role → 403 — the same routes, no-role context
27
+ * - credential-gated routes reject a disallowed credential → 403 — every
28
+ * route declaring `auth.credential_types`, probed on a channel it refuses
18
29
  * - correct auth passes guard — every protected route, assert not 401/403
19
30
  */
20
31
  export declare const describe_adversarial_auth: (options: AdversarialTestOptions) => void;
@@ -63,6 +74,14 @@ export interface StandardAttackSurfaceOptions {
63
74
  * to skip the assertion and keep the audit log informational-only.
64
75
  */
65
76
  error_schema_tightness?: ErrorSchemaTightnessOptions | null;
77
+ /**
78
+ * Routes the three adversarial sub-suites skip, in `'METHOD /path'` form
79
+ * — the escape hatch every sibling suite carries (`round_trip`,
80
+ * `data_exposure`). Reach for it only when a route cannot be driven
81
+ * generically at all; a route whose path params merely carry a format is
82
+ * handled by the params-schema-aware synthesizer.
83
+ */
84
+ skip_routes?: Array<string>;
66
85
  }
67
86
  /**
68
87
  * Run the standard attack surface test suite.
@@ -1 +1 @@
1
- {"version":3,"file":"attack_surface.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/attack_surface.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAoB7B,OAAO,EAQN,KAAK,4BAA4B,EACjC,KAAK,2BAA2B,EAChC,MAAM,yBAAyB,CAAC;AAoBjC,OAAO,EAA6B,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAsCpF,oFAAoF;AACpF,MAAM,WAAW,sBAAsB;IACtC,+EAA+E;IAC/E,KAAK,EAAE,MAAM,cAAc,CAAC;IAC5B,yDAAyD;IACzD,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;CACrB;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,yBAAyB,GAAI,SAAS,sBAAsB,KAAG,IA8H3E,CAAC;AAIF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,uCAAuC,GACnD,UAAU,2BAA2B,GAAG,IAAI,GAAG,SAAS,KACtD,2BAA2B,GAAG,IAWhC,CAAC;AAEF,0DAA0D;AAC1D,MAAM,WAAW,4BAA4B;IAC5C,+EAA+E;IAC/E,KAAK,EAAE,MAAM,cAAc,CAAC;IAC5B,yDAAyD;IACzD,aAAa,EAAE,MAAM,CAAC;IACtB,iFAAiF;IACjF,sBAAsB,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACtC,gHAAgH;IAChH,uBAAuB,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACvC,yDAAyD;IACzD,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACrB,qEAAqE;IACrE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iEAAiE;IACjE,eAAe,CAAC,EAAE,4BAA4B,CAAC;IAC/C;;;;;;;;;;;OAWG;IACH,sBAAsB,CAAC,EAAE,2BAA2B,GAAG,IAAI,CAAC;CAC5D;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,sCAAsC,GAClD,SAAS,4BAA4B,KACnC,IA2EF,CAAC"}
1
+ {"version":3,"file":"attack_surface.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/attack_surface.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAoB7B,OAAO,EAQN,KAAK,4BAA4B,EACjC,KAAK,2BAA2B,EAChC,MAAM,yBAAyB,CAAC;AAejC,OAAO,EAA6B,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAsDpF,oFAAoF;AACpF,MAAM,WAAW,sBAAsB;IACtC,+EAA+E;IAC/E,KAAK,EAAE,MAAM,cAAc,CAAC;IAC5B,yDAAyD;IACzD,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACrB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;CAC5B;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,yBAAyB,GAAI,SAAS,sBAAsB,KAAG,IA2J3E,CAAC;AAIF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,uCAAuC,GACnD,UAAU,2BAA2B,GAAG,IAAI,GAAG,SAAS,KACtD,2BAA2B,GAAG,IAWhC,CAAC;AAEF,0DAA0D;AAC1D,MAAM,WAAW,4BAA4B;IAC5C,+EAA+E;IAC/E,KAAK,EAAE,MAAM,cAAc,CAAC;IAC5B,yDAAyD;IACzD,aAAa,EAAE,MAAM,CAAC;IACtB,iFAAiF;IACjF,sBAAsB,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACtC,gHAAgH;IAChH,uBAAuB,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACvC,yDAAyD;IACzD,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACrB,qEAAqE;IACrE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iEAAiE;IACjE,eAAe,CAAC,EAAE,4BAA4B,CAAC;IAC/C;;;;;;;;;;;OAWG;IACH,sBAAsB,CAAC,EAAE,2BAA2B,GAAG,IAAI,CAAC;IAC5D;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,sCAAsC,GAClD,SAAS,4BAA4B,KACnC,IA4EF,CAAC"}