@fuzdev/fuz_app 0.89.0 → 0.91.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 (57) hide show
  1. package/dist/auth/CLAUDE.md +7 -0
  2. package/dist/auth/account_action_specs.d.ts +1 -1
  3. package/dist/auth/account_route_schema.d.ts +2 -2
  4. package/dist/auth/account_schema.d.ts +3 -3
  5. package/dist/auth/admin_action_specs.d.ts +8 -8
  6. package/dist/auth/all_cell_actions.d.ts +35 -0
  7. package/dist/auth/all_cell_actions.d.ts.map +1 -0
  8. package/dist/auth/all_cell_actions.js +32 -0
  9. package/dist/auth/audit_log_schema.d.ts +1 -1
  10. package/dist/auth/invite_schema.d.ts +2 -2
  11. package/dist/auth/signup_route_schema.d.ts +2 -2
  12. package/dist/auth/signup_route_schema.d.ts.map +1 -1
  13. package/dist/auth/signup_route_schema.js +2 -2
  14. package/dist/primitive_schemas.d.ts +27 -1
  15. package/dist/primitive_schemas.d.ts.map +1 -1
  16. package/dist/primitive_schemas.js +55 -2
  17. package/dist/server/env.d.ts +1 -1
  18. package/dist/server/env.d.ts.map +1 -1
  19. package/dist/server/env.js +15 -3
  20. package/dist/testing/CLAUDE.md +135 -10
  21. package/dist/testing/app_server.d.ts +16 -5
  22. package/dist/testing/app_server.d.ts.map +1 -1
  23. package/dist/testing/app_server.js +3 -1
  24. package/dist/testing/cross_backend/action_manifest.d.ts +113 -0
  25. package/dist/testing/cross_backend/action_manifest.d.ts.map +1 -0
  26. package/dist/testing/cross_backend/action_manifest.js +89 -0
  27. package/dist/testing/cross_backend/action_manifest_parity.d.ts +67 -0
  28. package/dist/testing/cross_backend/action_manifest_parity.d.ts.map +1 -0
  29. package/dist/testing/cross_backend/action_manifest_parity.js +88 -0
  30. package/dist/testing/cross_backend/capabilities.d.ts +47 -30
  31. package/dist/testing/cross_backend/capabilities.d.ts.map +1 -1
  32. package/dist/testing/cross_backend/capabilities.js +19 -4
  33. package/dist/testing/cross_backend/default_backend_configs.d.ts +31 -15
  34. package/dist/testing/cross_backend/default_backend_configs.d.ts.map +1 -1
  35. package/dist/testing/cross_backend/default_backend_configs.js +30 -14
  36. package/dist/testing/cross_backend/default_spine_surface.d.ts.map +1 -1
  37. package/dist/testing/cross_backend/default_spine_surface.js +6 -0
  38. package/dist/testing/cross_backend/full_spine_mount.d.ts +81 -0
  39. package/dist/testing/cross_backend/full_spine_mount.d.ts.map +1 -0
  40. package/dist/testing/cross_backend/full_spine_mount.js +49 -0
  41. package/dist/testing/cross_backend/identity_parity.d.ts +13 -0
  42. package/dist/testing/cross_backend/identity_parity.d.ts.map +1 -0
  43. package/dist/testing/cross_backend/identity_parity.js +465 -0
  44. package/dist/testing/cross_backend/method_coverage.d.ts +71 -0
  45. package/dist/testing/cross_backend/method_coverage.d.ts.map +1 -0
  46. package/dist/testing/cross_backend/method_coverage.js +89 -0
  47. package/dist/testing/cross_backend/setup.d.ts +21 -0
  48. package/dist/testing/cross_backend/setup.d.ts.map +1 -1
  49. package/dist/testing/cross_backend/setup.js +33 -1
  50. package/dist/testing/cross_backend/testing_backdoor.d.ts.map +1 -1
  51. package/dist/testing/cross_backend/testing_backdoor.js +9 -5
  52. package/dist/testing/cross_backend/testing_reset_actions.d.ts +76 -2
  53. package/dist/testing/cross_backend/testing_reset_actions.d.ts.map +1 -1
  54. package/dist/testing/cross_backend/testing_reset_actions.js +63 -2
  55. package/dist/testing/schema_generators.d.ts.map +1 -1
  56. package/dist/testing/schema_generators.js +7 -0
  57. package/package.json +2 -2
@@ -222,7 +222,37 @@ test-only by construction.
222
222
  - `assert_schema_snapshots_equal(a, b, labels?)` — throws on drift with a fully-formatted diff message.
223
223
  - `SchemaDiff` — tagged-union per drift kind: `table_only_in`, `column_only_in`, `column_field_differs`, `index_only_in`, `index_definition_differs`, `constraint_only_in`, `constraint_differs`, `sequence_only_in`, `sequence_data_type_differs`, `enum_only_in`, `enum_labels_differ` (enum labels compared positionally — declared order is significant).
224
224
 
225
- fuz_app's own spine gates this cross-process via the `cross_backend_schema_parity` project (`schema_parity.cross.test.ts` + the dual-spawn `global_setup_schema_parity.ts`), diffing the TS spine ↔ `testing_spine_stub` full schema — `npm run test:cross:schema-parity`. The forge has its own deno↔rust parity gate.
225
+ fuz_app's own spine gates this cross-process via the `cross_backend_parity` project (`schema_parity.cross.test.ts` + the dual-spawn `global_setup_schema_parity.ts`), diffing the TS spine ↔ `testing_spine_stub` full schema — `npm run test:cross:parity`. The forge has its own deno↔rust parity gate.
226
+
227
+ ## Cross-impl RPC-manifest parity
228
+
229
+ The action-surface sibling of schema parity. Where schema parity diffs the live
230
+ _database_ shape, this diffs the live _RPC registry_ shape — proving the TS
231
+ spine and the Rust `testing_spine_stub` mount the same method set with the same
232
+ per-method auth shape.
233
+
234
+ - `cross_backend/action_manifest.ts` — `ActionManifest` / `ActionManifestEntry`
235
+ Zod schema (the `_testing_action_manifest` wire validator) + `build_action_manifest(specs)`,
236
+ which normalizes each spec to `{method, side_effects, account, actor, roles,
237
+ credential_types}` (auth axes pass through; `roles` / `credential_types` flatten
238
+ to sorted arrays). Twin of `schema_introspect.ts`. Excludes the protocol actions
239
+ (`heartbeat` / `cancel`) by construction — the two impls organize them
240
+ differently (TS WS-only; Rust on one shared registry), so the caller passes a
241
+ protocol-free list.
242
+ - `cross_backend/action_manifest_parity.ts` — `diff_action_manifests` /
243
+ `format_action_manifest_diffs` / `assert_action_manifests_equal` (twin of
244
+ `schema_parity.ts`) — asserts exact method-set + per-method auth-shape parity.
245
+ - `cross_backend/setup.ts` `capture_action_manifest(handle)` — dumps a backend's
246
+ manifest over the daemon-token `_testing_action_manifest` channel (twin of
247
+ `capture_schema_snapshot`).
248
+
249
+ It runs under the same dual-spawn `cross_backend_parity` project (one TS-spine +
250
+ Rust-stub spawn serves both gates). It complements the in-repo
251
+ `spine_method_coverage` reconciliation gate (which proves _mounted ⟹ covered_);
252
+ this proves _TS-mount-set ≡ Rust-mount-set_. The gate asserts **exact** parity —
253
+ every mounted method and its full auth shape (side-effects + the four auth axes)
254
+ must match across the two impls, with no allowlisted divergences (see
255
+ `action_manifest_parity.cross.test.ts`).
226
256
 
227
257
  **Cross-impl gate pattern** — a dual-impl consumer running two backends
228
258
  (a TS Hono server and a Rust spine server) against a shared schema, plus
@@ -840,7 +870,12 @@ source of truth for wire-shape conformance.
840
870
  whose `RoleSpec.grant_paths` don't include `'admin'` reject loudly at
841
871
  offer-create time (`ERROR_ROLE_GRANT_OFFER_ROLE_NOT_GRANTABLE`); those
842
872
  roles must be seeded via `extra_accounts` at bootstrap-equivalent time
843
- instead. Caller-supplied `username`s pass through _as-is_ now that the DB
873
+ instead. `create_account({email})` threads an email onto the signup body
874
+ (the username-scoped invite matches regardless of email), so the account
875
+ lands with an email set — the hook the username-or-email login parity suite
876
+ uses; the in-process path sets it directly on the inserted row. Must be a
877
+ valid, per-test-unique `Email` (the `LOWER(email)` partial-unique index
878
+ rejects collisions). Caller-supplied `username`s pass through _as-is_ now that the DB
844
879
  wipes between tests — hardcoded names like `'user_two'` work and the
845
880
  earlier uniquification prefix is gone. Every `TestFixture` also exposes
846
881
  `fresh_transport({origin?: string | null})` — cookie-jar-free probe;
@@ -856,18 +891,26 @@ source of truth for wire-shape conformance.
856
891
  deliver it.
857
892
 
858
893
  - `testing/cross_backend/capabilities.ts` — `BackendCapabilities` vocabulary
859
- (`bearer_auth` / `trusted_proxy` / `login_rate_limit` / `ws` / `sse` /
860
- `cell_crud` / `cell_relations` / `account_lifecycle` / `fact_serving` /
861
- `ready` / `account_status` / `oversized_reject_closes_connection`),
894
+ (the **gating** flags `ws` / `sse` / `cell_crud` / `cell_relations` /
895
+ `account_lifecycle` / `fact_serving` / `ready` / `account_status` /
896
+ `oversized_reject_closes_connection` — each has a `test_if` reader),
862
897
  `test_if(cond, name, fn)`
863
- for capability-gated cases, and `in_process_capabilities` preset. `cell_crud`
898
+ for capability-gated cases, and `in_process_capabilities` preset. The
899
+ non-gating wiring facts (`bearer_auth` / `trusted_proxy` / `login_rate_limit`,
900
+ no `test_if` readers) live in the parallel `BackendShapeNotes` record
901
+ (`in_process_shape_notes`; `ts_default_shape_notes` / `rust_default_shape_notes`
902
+ in `default_backend_configs.ts`) — split out so the capability type stops
903
+ claiming gating it doesn't do. `cell_crud`
864
904
  gates the CRUD parity suite, `cell_relations` the relation / ACL / audit
865
905
  parity suite — both `true` on every backend that live-mounts the full cell
866
906
  surface (TS spine binary, in-process app, Rust stub). A backend mounting only
867
907
  plain CRUD would declare `cell_crud: true, cell_relations: false`.
868
908
  `account_lifecycle` gates `describe_account_lifecycle_cross_tests` (the
869
- `account_delete` / `account_undelete` / `account_purge` parity suite) — also
870
- off the declared surface like cells, `true` on every spine. `fact_serving`
909
+ `account_delete` / `account_undelete` / `account_purge` parity suite); unlike
910
+ cells those verbs **are** on the declared surface (in `create_admin_actions`,
911
+ auto-enumerated for shape/auth) — the flag gates the behavioral parity the
912
+ generic round-trip can't drive (it can't delete the subject). `true` on every
913
+ spine. `fact_serving`
871
914
  gates `describe_fact_serving_cross_tests` (the cell-scoped per-reference +
872
915
  admin-only bare-hash fact-serving parity suite); like cells it stays off the
873
916
  declared surface and is `true` on every spine that mounts the serve routes +
@@ -1186,6 +1229,16 @@ in-process legs (plain `gro test`) are `src/test/auth/cell_crud_parity.db.test.t
1186
1229
  payload-expiry tests never reached. Daemon-token-gated like its siblings; the
1187
1230
  Rust mirror is `fuz_testing::create_testing_mint_session_action_spec`.
1188
1231
 
1232
+ Also in the module — but **not** bundled by `create_testing_actions` —
1233
+ `_testing_action_manifest` (+ `create_testing_action_manifest_action(mounted)`):
1234
+ dumps the live RPC registry as a normalized `ActionManifest` for the
1235
+ cross-impl manifest-parity gate (see §Cross-impl RPC-manifest parity). It must
1236
+ enumerate _every_ mounted method, which `create_testing_actions` (one
1237
+ sub-factory) can't see, so it's appended at the full-mount layer
1238
+ (`full_spine_mount.ts` `build_full_spine_rpc_actions`), closing over the
1239
+ complete action list plus its own spec. Daemon-token-gated like its siblings;
1240
+ the Rust mirror is `fuz_testing::create_testing_action_manifest_action_spec`.
1241
+
1189
1242
  ### Origin verification parity — `cross_backend/origin.ts`
1190
1243
 
1191
1244
  `describe_origin_cross_tests({setup_test, capabilities, rpc_path?})` — the
@@ -1247,6 +1300,53 @@ in-process spec-level gate test (`src/test/testing/testing_actions_auth.test.ts`
1247
1300
  asserting each spec declares `credential_types: ['daemon_token']`) + the
1248
1301
  `assert_no_testing_methods` surface invariant.
1249
1302
 
1303
+ ### Identity-primitive parity — `cross_backend/identity_parity.ts`
1304
+
1305
+ `describe_identity_parity_cross_tests({setup_test, login_path?, signup_path?})` —
1306
+ the imperative suite pinning the `primitive_schemas` twins (`Username`,
1307
+ `UsernameProvided`, `Email`) + login/signup input handling end-to-end over real
1308
+ HTTP (flat REST `/login` + `/signup`, so imperative, not a `conformance_table`
1309
+ row). Six facets, each a TS↔Rust reimplementation pair that the spec-derived
1310
+ round-trip / conformance suites never vary:
1311
+
1312
+ - **Login canonicalization** — case-insensitive + whitespace-trim lookup
1313
+ (`UsernameProvided` `.trim().toLowerCase()` + `LOWER(username)`), plus a
1314
+ Turkish-`İ` homograph **no-Unicode-fold-collision** negative.
1315
+ - **Username-or-email login** — an account created with an email logs in via
1316
+ that email, case-insensitively both directions; username login still works;
1317
+ non-existent email → 401. This is the corner that surfaced and closed the Rust
1318
+ spine's username-only divergence (it now mirrors TS's
1319
+ `query_account_by_username_or_email`).
1320
+ - **Login input validation** — malformed login input → 400 `invalid_request_body`
1321
+ on every spine: whitespace-only username (empty after trim), over-long username
1322
+ (> 255), empty password, unknown body key (strict object). TS runs the full
1323
+ `LoginInput` Zod schema; the Rust spine enforces the same shape in
1324
+ `account_login` (closed a cluster where three of these fell through to a
1325
+ lookup-miss 401 on Rust and a whitespace-only identifier 401'd on TS). Asserted
1326
+ by error reason, not just status.
1327
+ - **ASCII-only creation invariant** — non-ASCII username → 400 at signup.
1328
+ - **Length + format regex parity** — both `[USERNAME_LENGTH_MIN,
1329
+ USERNAME_LENGTH_MAX]` = `[3, 39]` boundary edges (just-outside → 400,
1330
+ just-inside → 403 no-matching-invite) and the creation regex shape (leading
1331
+ non-letter / trailing punctuation / embedded disallowed char → 400; mid-string
1332
+ `_`/`-` accepted), catching an off-by-one or position bug in the TS Zod
1333
+ `.min/.max/.regex` vs the Rust byte-scan `is_valid_username_for_creation`.
1334
+ - **Email format (creation)** — the optional signup `email` validated to the
1335
+ loose `local@domain.tld` shape (TS `Email` `^[^\s@]+@[^\s@]+\.[^\s@]+$` + 254-byte
1336
+ bound, Rust `is_valid_email`): malformed (no `@` / no domain dot / empty
1337
+ side / dot at a domain edge / whitespace / over-length) → 400, well-formed →
1338
+ 403 no-invite. Accepted siblings include the single-char-TLD `a@b.c` that
1339
+ Zod's `z.email()` rejects — the deliberately-looser shared rule. **Closed a
1340
+ real divergence**: the Rust spine previously length-checked the email only,
1341
+ accepting any non-empty string TS rejected.
1342
+
1343
+ Ungated (login + signup are on every spine). Runs both legs via the shared
1344
+ `{setup_test}` protocol: in-process (`identity_parity.db.test.ts`, plain
1345
+ `gro test`) and cross-process (`identity_parity.cross.test.ts`). `$lib`-free.
1346
+ The accepted-case 403s rely on `create_spine_route_specs` zeroing
1347
+ `signup_fail_floor_ms` (mirroring `login_fail_floor_ms: 0`) so they don't each
1348
+ pay the 250ms denial floor.
1349
+
1250
1350
  ### Building a TS test-server binary — `testing_server_core.ts` + adapters
1251
1351
 
1252
1352
  The reusable shape for standing up a **spawnable TS** cross-process test
@@ -1257,10 +1357,35 @@ re-roll the serve / daemon-info / WS-attach / drain boilerplate:
1257
1357
  - `testing/cross_backend/testing_server_node.ts` — `create_node_testing_adapter()` (`@hono/node-server` + `@hono/node-ws`). Optional peer deps (like `ws`); only test binaries import them.
1258
1358
  - `testing/cross_backend/testing_server_deno.ts` — `create_deno_testing_adapter()` (`Deno.serve` + `hono/deno`; `Deno` declared locally so it typechecks under the Node toolchain). Spawn the entry with `--sloppy-imports` (Deno doesn't do `.js`→`.ts`; Gro's loader does, so the Node path needs no flag).
1259
1359
  - `testing/cross_backend/testing_server_bun.ts` — `create_bun_testing_adapter()` (`Bun.serve` + `hono/bun`'s module-level `upgradeWebSocket` + `websocket`; `Bun.serve` declared locally so it typechecks under the Node toolchain). **No extra deps** (`hono/bun` ships with `hono`; `Bun.serve` is built in, unlike Node's `@hono/node-server` + `@hono/node-ws`), and Bun resolves `.js`→`.ts` natively (no flag, unlike Deno). Reuses `create_node_runtime` (Bun implements the `node:fs`/`node:process` surface). WS is module-level + stateless (like Deno) — the `websocket` handler is threaded into `serve`, where `Bun.serve` wants it, so no post-serve attach.
1260
- - `testing/cross_backend/default_spine_surface.ts` — the canonical no-domain spine surface (account/admin/audit/signup + bootstrap): `spine_session_options`, `spine_roles`, `create_spine_route_specs`, `spine_rpc_endpoints`, `create_spine_surface_spec`. `$lib`-free (it's reached by the spawned binary under Gro's loader, which doesn't resolve `$lib`), so keep it on relative imports. Shared by the spine_stub cross test, the TS cross tests, and the binary.
1360
+ - `testing/cross_backend/default_spine_surface.ts` — the canonical no-domain spine surface (account/admin/audit/signup + bootstrap): `spine_session_options`, `spine_roles`, `create_spine_route_specs`, `spine_rpc_endpoints`, `create_spine_surface_spec`. This is the **declared** surface — the `create_standard_rpc_actions` bundle the spec-derived suites auto-enumerate. `$lib`-free (it's reached by the spawned binary under Gro's loader, which doesn't resolve `$lib`), so keep it on relative imports. Shared by the spine_stub cross test, the TS cross tests, and the binary.
1361
+ - `testing/cross_backend/full_spine_mount.ts` — `build_full_spine_rpc_actions(deps, options)` / `full_spine_rpc_endpoints(ctx, options)` — the **full** live RPC mount: the declared bundle **plus** the off-declared-surface families the binary live-mounts (`_testing_*` backdoors, the cell verb set, the opt-in `actor_lookup` / `actor_search` resolvers). Single-sources what was an inline assembly in `testing_spine_server.ts`, so the binary and the `spine_method_coverage` reconciliation test build the same list. Also `$lib`-free.
1261
1362
  - `testing/cross_backend/ts_spine_backend_config.ts` — `ts_spine_node_backend_config()` / `ts_spine_deno_backend_config()` / `ts_spine_bun_backend_config()` presets (in-memory PGlite, no external infra), the TS analog of `rust_spine_stub_backend_config()`.
1262
1363
 
1263
- fuz_app's own binary wiring (`src/test/cross_backend/testing_spine_server{,_node,_deno,_bun}.ts`) is the worked example: ~one `build_app` over `create_app_backend` + `create_app_server` + `_testing_reset` + a WS mount, reusing `default_spine_surface`. The `_node`/`_deno`/`_bun` entries differ only in which adapter they wire — `build_spine_app` is runtime-agnostic.
1364
+ fuz_app's own binary wiring (`src/test/cross_backend/testing_spine_server{,_node,_deno,_bun}.ts`) is the worked example: ~one `build_app` over `create_app_backend` + `create_app_server` + `full_spine_rpc_endpoints` + a WS mount, reusing `default_spine_surface`. The `_node`/`_deno`/`_bun` entries differ only in which adapter they wire — `build_spine_app` is runtime-agnostic.
1365
+
1366
+ ### Live-method coverage reconciliation — `method_coverage.ts`
1367
+
1368
+ `assert_rpc_method_coverage({live_methods, declared_methods, manifest})` keeps
1369
+ the **off-declared-surface** methods as drift-proof as the declared ones. The
1370
+ spec-derived suites auto-enumerate the declared surface, but a backend's live
1371
+ RPC endpoint also mounts methods kept off it (stateful cell verbs, opt-in
1372
+ resolvers, `_testing_*` backdoors) that rely on hand-wired imperative suites —
1373
+ nothing structurally guaranteed every live method was actually claimed by one.
1374
+
1375
+ The assertion diffs the live method set against a `MethodCoverageEntry`
1376
+ manifest both directions (a mounted-but-unclaimed method **and** a stale
1377
+ manifest row both fail loud) and checks each entry's `tier`
1378
+ (`declared` / `off_surface` / `backdoor`) is consistent with the declared
1379
+ surface + the `_testing_` prefix. `off_surface` rows must name the covering
1380
+ `suite`; `capability` is typed `keyof BackendCapabilities` so a stale flag is a
1381
+ compile error. The manifest is the forcing function — a method can't reach the
1382
+ live mount without a row naming its coverage.
1383
+
1384
+ Pairs with `surface_invariants.ts` `assert_no_testing_methods` (the _reverse_
1385
+ guard — a backdoor must never leak _onto_ the declared surface). fuz_app's own
1386
+ wiring is the manifest `src/test/cross_backend/spine_method_coverage.ts` + the
1387
+ no-DB reconciliation test `spine_method_coverage.test.ts`, which enumerates
1388
+ `build_full_spine_rpc_actions` with stub deps against `create_spine_surface_spec`.
1264
1389
 
1265
1390
  The in-process `ws_round_trip` harness stays (it drives the dispatcher
1266
1391
  against a fake upgrade, no wire), but the real-upgrade coverage now lives in
@@ -48,6 +48,8 @@ export interface CreateTestAccountWithCredentialsOptions {
48
48
  username?: string;
49
49
  password_value?: string;
50
50
  roles?: Array<string>;
51
+ /** Optional email stored on the account row — exercises the username-or-email login lookup. */
52
+ email?: string;
51
53
  }
52
54
  /** Alias for the keeper-flavored call site. Same shape. */
53
55
  export type BootstrapTestKeeperOptions = CreateTestAccountWithCredentialsOptions;
@@ -269,6 +271,19 @@ export interface TestAccount {
269
271
  /** Build request headers with this account's Bearer token. */
270
272
  create_bearer_headers: (extra?: Record<string, string>) => Record<string, string>;
271
273
  }
274
+ /**
275
+ * Args for `TestApp.create_account` — mint an additional account alongside the
276
+ * keeper. Mirrors the cross-process `CreateTestAccountOptions` (the two
277
+ * `create_account` paths share a shape so fixture call sites read identically),
278
+ * kept local to avoid a cross-module cycle with `cross_backend/setup.ts`.
279
+ */
280
+ export interface CreateTestAppAccountArgs {
281
+ username?: string;
282
+ password_value?: string;
283
+ roles?: Array<string>;
284
+ /** Optional email stored on the account row — exercises the username-or-email login lookup. */
285
+ email?: string;
286
+ }
272
287
  /**
273
288
  * A fully assembled test app — Hono app + backend + helpers.
274
289
  */
@@ -285,11 +300,7 @@ export interface TestApp {
285
300
  /** Build request headers with the daemon token (keeper auth). */
286
301
  create_daemon_token_headers: (extra?: Record<string, string>) => Record<string, string>;
287
302
  /** Create an additional account with credentials. */
288
- create_account: (options?: {
289
- username?: string;
290
- password_value?: string;
291
- roles?: Array<string>;
292
- }) => Promise<TestAccount>;
303
+ create_account: (options?: CreateTestAppAccountArgs) => Promise<TestAccount>;
293
304
  /** Cleanup resources (delegates to TestAppServer.cleanup). */
294
305
  cleanup: () => Promise<void>;
295
306
  }
@@ -1 +1 @@
1
- {"version":3,"file":"app_server.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/app_server.ts"],"names":[],"mappings":"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"}
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,EAAC,IAAI,EAAC,MAAM,MAAM,CAAC;AAG/B,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,wBAAwB,CAAC;AAIjD,OAAO,EAA2B,KAAK,OAAO,EAAC,MAAM,oBAAoB,CAAC;AAE1E,OAAO,KAAK,EAAC,EAAE,EAAE,MAAM,EAAC,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,qBAAqB,CAAC;AAU1D,OAAO,EAA8B,KAAK,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAC3F,OAAO,EAAiB,KAAK,kBAAkB,EAAC,MAAM,kBAAkB,CAAC;AAEzE,OAAO,EAAwB,KAAK,UAAU,EAAE,KAAK,YAAY,EAAC,MAAM,0BAA0B,CAAC;AACnG,OAAO,EAEN,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,EAC3B,KAAK,oBAAoB,EACzB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,iCAAiC,CAAC;AACtE,OAAO,KAAK,EAAC,UAAU,EAAE,cAAc,EAAC,MAAM,oBAAoB,CAAC;AACnE,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAOrD,OAAO,KAAK,EAAC,uBAAuB,EAAC,MAAM,kBAAkB,CAAC;AAE9D;;;;;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;QAAC,EAAE,EAAE,IAAI,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAC,CAAC;IACtC,KAAK,EAAE;QAAC,EAAE,EAAE,IAAI,CAAA;KAAC,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;CACvB,CA8CA,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;IAAC,cAAc,EAAE,MAAM,CAAA;CAAC,CAQlC,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,qBAAqB,GACjC,SAAS,0BAA0B,KACjC,OAAO,CAAC;IACV,OAAO,EAAE;QAAC,EAAE,EAAE,IAAI,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAC,CAAC;IACtC,KAAK,EAAE;QAAC,EAAE,EAAE,IAAI,CAAA;KAAC,CAAC;IAClB,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;QAAC,EAAE,EAAE,IAAI,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAC,CAAC;IACtC,uCAAuC;IACvC,KAAK,EAAE;QAAC,EAAE,EAAE,IAAI,CAAA;KAAC,CAAC;IAClB,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;AAuID,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;QAAC,EAAE,EAAE,IAAI,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAC,CAAC;IACtC,KAAK,EAAE;QAAC,EAAE,EAAE,IAAI,CAAA;KAAC,CAAC;IAClB,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,CAmGpF,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,CAuE7B,CAAC"}
@@ -78,12 +78,13 @@ const resolve_fallback_factory = (migration_namespaces) => {
78
78
  * `role_grant` (one per role), `api_token`, and `auth_session`.
79
79
  */
80
80
  export const create_test_account_with_credentials = async (options) => {
81
- const { db, keyring, session_options, password, username = 'keeper', password_value = DEFAULT_TEST_PASSWORD, roles = [], } = options;
81
+ const { db, keyring, session_options, password, username = 'keeper', password_value = DEFAULT_TEST_PASSWORD, roles = [], email, } = options;
82
82
  const deps = { db };
83
83
  const password_hash = await password.hash_password(password_value);
84
84
  const { account, actor } = await query_create_account_with_actor(deps, {
85
85
  username,
86
86
  password_hash,
87
+ ...(email !== undefined && { email }),
87
88
  });
88
89
  // Grant roles
89
90
  for (const role of roles) {
@@ -315,6 +316,7 @@ export const create_test_app = async (options) => {
315
316
  username: account_options?.username ?? `test_user_${account_counter}`,
316
317
  password_value: account_options?.password_value ?? DEFAULT_TEST_PASSWORD,
317
318
  roles: account_options?.roles ?? [],
319
+ ...(account_options?.email !== undefined && { email: account_options.email }),
318
320
  });
319
321
  return {
320
322
  ...bootstrapped,
@@ -0,0 +1,113 @@
1
+ import '../assert_dev_env.js';
2
+ /**
3
+ * Cross-impl RPC **action-manifest** introspection — a normalized,
4
+ * JSON-serializable dump of a backend's live RPC method set, one entry per
5
+ * method carrying its auth shape + side-effect flag.
6
+ *
7
+ * The sibling of `schema_introspect.ts`'s `SchemaSnapshot`: where that
8
+ * captures the live *database* shape for the schema-parity gate, this
9
+ * captures the live *RPC registry* shape for the action-manifest parity gate.
10
+ * Both are dumped over a daemon-token `_testing_*` introspection action
11
+ * (`_testing_action_manifest` here, `_testing_schema_snapshot` there) and
12
+ * diffed across the TS spine and the Rust `testing_spine_stub` so a
13
+ * method-set or per-method auth-shape divergence fails loud. This complements
14
+ * the in-repo `spine_method_coverage` gate: that proves *mounted ⟹ covered*;
15
+ * this proves *TS-mount-set ≡ Rust-mount-set* (method set + auth shape).
16
+ *
17
+ * **Scope — domain + testing surface, not wire protocol.** The manifest is
18
+ * built from exactly the spec list its caller passes
19
+ * (`build_full_spine_rpc_actions` on the TS spine; the spec list minus
20
+ * `PROTOCOL_ACTION_SPECS` on the Rust stub). The protocol actions
21
+ * (`heartbeat` / `cancel`) are excluded by the caller on purpose: the two
22
+ * impls organize them differently (the TS spine mounts them on the WS
23
+ * endpoint only, never the HTTP-RPC endpoint; the Rust stub compiles one
24
+ * shared registry serving both transports), so including them would be a
25
+ * spurious cross-impl diff. This matches the scope of the in-repo
26
+ * `spine_method_coverage` gate (also over `build_full_spine_rpc_actions`).
27
+ *
28
+ * Paired with `action_manifest_parity.ts` for the diff + assertion helpers.
29
+ *
30
+ * `$lib`-free by contract — reached by the spawned TS binary (via
31
+ * `testing_reset_actions.ts` → `full_spine_mount.ts`), so every import is
32
+ * relative.
33
+ *
34
+ * @module
35
+ */
36
+ import { z } from 'zod';
37
+ import { type RouteAuth } from '../../http/auth_shape.js';
38
+ import type { RequestResponseActionSpec } from '../../actions/action_spec.js';
39
+ /**
40
+ * One method's normalized RPC metadata — the cross-impl-comparable unit.
41
+ * `roles` / `credential_types` are always present + sorted (an absent gate
42
+ * and an empty list both serialize to `[]`) so the diff never trips on a
43
+ * `undefined`-vs-`[]` or declaration-order difference between impls; the
44
+ * auth axes reuse the canonical `AuthAxisState` enum.
45
+ */
46
+ export declare const ActionManifestEntry: z.ZodObject<{
47
+ /** RPC method name (`spec.method`). */
48
+ method: z.ZodString;
49
+ /** `true` when the action declares `side_effects` (mutation; POST-only on the RPC transport). */
50
+ side_effects: z.ZodBoolean;
51
+ /** The `account` auth axis. */
52
+ account: z.ZodEnum<{
53
+ optional: "optional";
54
+ none: "none";
55
+ required: "required";
56
+ }>;
57
+ /** The `actor` auth axis. */
58
+ actor: z.ZodEnum<{
59
+ optional: "optional";
60
+ none: "none";
61
+ required: "required";
62
+ }>;
63
+ /** Required roles (any-of), sorted; `[]` when the action declares no role gate. */
64
+ roles: z.ZodArray<z.ZodString>;
65
+ /** Permitted credential channels, sorted; `[]` when ungated (any credential). */
66
+ credential_types: z.ZodArray<z.ZodString>;
67
+ }, z.core.$strict>;
68
+ export type ActionManifestEntry = z.infer<typeof ActionManifestEntry>;
69
+ /** The full action manifest — every entry, sorted by `method`. */
70
+ export declare const ActionManifest: z.ZodObject<{
71
+ methods: z.ZodArray<z.ZodObject<{
72
+ /** RPC method name (`spec.method`). */
73
+ method: z.ZodString;
74
+ /** `true` when the action declares `side_effects` (mutation; POST-only on the RPC transport). */
75
+ side_effects: z.ZodBoolean;
76
+ /** The `account` auth axis. */
77
+ account: z.ZodEnum<{
78
+ optional: "optional";
79
+ none: "none";
80
+ required: "required";
81
+ }>;
82
+ /** The `actor` auth axis. */
83
+ actor: z.ZodEnum<{
84
+ optional: "optional";
85
+ none: "none";
86
+ required: "required";
87
+ }>;
88
+ /** Required roles (any-of), sorted; `[]` when the action declares no role gate. */
89
+ roles: z.ZodArray<z.ZodString>;
90
+ /** Permitted credential channels, sorted; `[]` when ungated (any credential). */
91
+ credential_types: z.ZodArray<z.ZodString>;
92
+ }, z.core.$strict>>;
93
+ }, z.core.$strict>;
94
+ export type ActionManifest = z.infer<typeof ActionManifest>;
95
+ /**
96
+ * Normalize one spec's auth + side-effects into a manifest entry. Pulls the
97
+ * four auth axes off `RouteAuth` (the same shape the Rust `AuthSpec` mirrors)
98
+ * and flattens optional `roles` / `credential_types` to sorted arrays.
99
+ */
100
+ export declare const action_manifest_entry: (spec: {
101
+ readonly method: string;
102
+ readonly auth: RouteAuth;
103
+ readonly side_effects: boolean;
104
+ }) => ActionManifestEntry;
105
+ /**
106
+ * Build the normalized `ActionManifest` from a list of request-response
107
+ * specs. Entries are sorted by `method` so two impls producing the same set
108
+ * serialize identically regardless of mount order. The caller owns the scope
109
+ * it passes (the TS spine passes its full mount; the Rust stub filters
110
+ * `PROTOCOL_ACTION_SPECS` first) — see the module doc.
111
+ */
112
+ export declare const build_action_manifest: (specs: ReadonlyArray<Pick<RequestResponseActionSpec, "method" | "auth" | "side_effects">>) => ActionManifest;
113
+ //# sourceMappingURL=action_manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action_manifest.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/action_manifest.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAE9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAEtB,OAAO,EAAgB,KAAK,SAAS,EAAC,MAAM,0BAA0B,CAAC;AACvE,OAAO,KAAK,EAAC,yBAAyB,EAAC,MAAM,8BAA8B,CAAC;AAE5E;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB;IAC/B,uCAAuC;;IAEvC,iGAAiG;;IAEjG,+BAA+B;;;;;;IAE/B,6BAA6B;;;;;;IAE7B,mFAAmF;;IAEnF,iFAAiF;;kBAEhF,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEtE,kEAAkE;AAClE,eAAO,MAAM,cAAc;;QAhB1B,uCAAuC;;QAEvC,iGAAiG;;QAEjG,+BAA+B;;;;;;QAE/B,6BAA6B;;;;;;QAE7B,mFAAmF;;QAEnF,iFAAiF;;;kBAQhF,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAM5D;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,GAAI,MAAM;IAC3C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;CAC/B,KAAG,mBAOF,CAAC;AAMH;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,GACjC,OAAO,aAAa,CAAC,IAAI,CAAC,yBAAyB,EAAE,QAAQ,GAAG,MAAM,GAAG,cAAc,CAAC,CAAC,KACvF,cAED,CAAC"}
@@ -0,0 +1,89 @@
1
+ import '../assert_dev_env.js';
2
+ /**
3
+ * Cross-impl RPC **action-manifest** introspection — a normalized,
4
+ * JSON-serializable dump of a backend's live RPC method set, one entry per
5
+ * method carrying its auth shape + side-effect flag.
6
+ *
7
+ * The sibling of `schema_introspect.ts`'s `SchemaSnapshot`: where that
8
+ * captures the live *database* shape for the schema-parity gate, this
9
+ * captures the live *RPC registry* shape for the action-manifest parity gate.
10
+ * Both are dumped over a daemon-token `_testing_*` introspection action
11
+ * (`_testing_action_manifest` here, `_testing_schema_snapshot` there) and
12
+ * diffed across the TS spine and the Rust `testing_spine_stub` so a
13
+ * method-set or per-method auth-shape divergence fails loud. This complements
14
+ * the in-repo `spine_method_coverage` gate: that proves *mounted ⟹ covered*;
15
+ * this proves *TS-mount-set ≡ Rust-mount-set* (method set + auth shape).
16
+ *
17
+ * **Scope — domain + testing surface, not wire protocol.** The manifest is
18
+ * built from exactly the spec list its caller passes
19
+ * (`build_full_spine_rpc_actions` on the TS spine; the spec list minus
20
+ * `PROTOCOL_ACTION_SPECS` on the Rust stub). The protocol actions
21
+ * (`heartbeat` / `cancel`) are excluded by the caller on purpose: the two
22
+ * impls organize them differently (the TS spine mounts them on the WS
23
+ * endpoint only, never the HTTP-RPC endpoint; the Rust stub compiles one
24
+ * shared registry serving both transports), so including them would be a
25
+ * spurious cross-impl diff. This matches the scope of the in-repo
26
+ * `spine_method_coverage` gate (also over `build_full_spine_rpc_actions`).
27
+ *
28
+ * Paired with `action_manifest_parity.ts` for the diff + assertion helpers.
29
+ *
30
+ * `$lib`-free by contract — reached by the spawned TS binary (via
31
+ * `testing_reset_actions.ts` → `full_spine_mount.ts`), so every import is
32
+ * relative.
33
+ *
34
+ * @module
35
+ */
36
+ import { z } from 'zod';
37
+ import { AuthAxisState } from '../../http/auth_shape.js';
38
+ /**
39
+ * One method's normalized RPC metadata — the cross-impl-comparable unit.
40
+ * `roles` / `credential_types` are always present + sorted (an absent gate
41
+ * and an empty list both serialize to `[]`) so the diff never trips on a
42
+ * `undefined`-vs-`[]` or declaration-order difference between impls; the
43
+ * auth axes reuse the canonical `AuthAxisState` enum.
44
+ */
45
+ export const ActionManifestEntry = z.strictObject({
46
+ /** RPC method name (`spec.method`). */
47
+ method: z.string(),
48
+ /** `true` when the action declares `side_effects` (mutation; POST-only on the RPC transport). */
49
+ side_effects: z.boolean(),
50
+ /** The `account` auth axis. */
51
+ account: AuthAxisState,
52
+ /** The `actor` auth axis. */
53
+ actor: AuthAxisState,
54
+ /** Required roles (any-of), sorted; `[]` when the action declares no role gate. */
55
+ roles: z.array(z.string()),
56
+ /** Permitted credential channels, sorted; `[]` when ungated (any credential). */
57
+ credential_types: z.array(z.string()),
58
+ });
59
+ /** The full action manifest — every entry, sorted by `method`. */
60
+ export const ActionManifest = z.strictObject({
61
+ methods: z.array(ActionManifestEntry),
62
+ });
63
+ /** Sorted copy of a readonly string list (stable cross-impl ordering). */
64
+ const sorted_strings = (xs) => [...(xs ?? [])].sort();
65
+ /**
66
+ * Normalize one spec's auth + side-effects into a manifest entry. Pulls the
67
+ * four auth axes off `RouteAuth` (the same shape the Rust `AuthSpec` mirrors)
68
+ * and flattens optional `roles` / `credential_types` to sorted arrays.
69
+ */
70
+ export const action_manifest_entry = (spec) => ({
71
+ method: spec.method,
72
+ side_effects: spec.side_effects,
73
+ account: spec.auth.account,
74
+ actor: spec.auth.actor,
75
+ roles: sorted_strings(spec.auth.roles),
76
+ credential_types: sorted_strings(spec.auth.credential_types),
77
+ });
78
+ /** Deterministic byte-lexicographic method order — matches the Rust `str::cmp` the stub sorts by. */
79
+ const compare_method = (a, b) => a.method < b.method ? -1 : a.method > b.method ? 1 : 0;
80
+ /**
81
+ * Build the normalized `ActionManifest` from a list of request-response
82
+ * specs. Entries are sorted by `method` so two impls producing the same set
83
+ * serialize identically regardless of mount order. The caller owns the scope
84
+ * it passes (the TS spine passes its full mount; the Rust stub filters
85
+ * `PROTOCOL_ACTION_SPECS` first) — see the module doc.
86
+ */
87
+ export const build_action_manifest = (specs) => ({
88
+ methods: specs.map(action_manifest_entry).sort(compare_method),
89
+ });
@@ -0,0 +1,67 @@
1
+ import '../assert_dev_env.js';
2
+ /**
3
+ * Cross-impl action-manifest parity — structural diff + assertion over two
4
+ * `ActionManifest`s captured via the `_testing_action_manifest` RPC action.
5
+ *
6
+ * The action-surface twin of `schema_parity.ts`: two live impls (the TS
7
+ * fuz_app spine and the Rust `testing_spine_stub`) are each other's parity
8
+ * reference. After both bootstrap, dump each one's live RPC method set, diff,
9
+ * fail loudly on drift. The diff entries name the specific divergence (a
10
+ * method only one impl mounts, a per-method auth-axis or side-effect
11
+ * mismatch) so the error message points at the source.
12
+ *
13
+ * ```ts
14
+ * const manifest_a = await capture_action_manifest(ts_handle);
15
+ * const manifest_b = await capture_action_manifest(rust_handle);
16
+ * assert_action_manifests_equal(manifest_a, manifest_b, {a: 'ts', b: 'rust'});
17
+ * ```
18
+ *
19
+ * Non-coverage: the manifest captures `{method, side_effects, account, actor,
20
+ * roles, credential_types}` — the wire-relevant auth shape. It does **not**
21
+ * capture input/output schemas (the declared-surface wire shape is gated by
22
+ * `rpc_round_trip`) nor the protocol actions `heartbeat` / `cancel` (excluded
23
+ * by construction — see `action_manifest.ts`).
24
+ *
25
+ * @module
26
+ */
27
+ import type { ActionManifest } from './action_manifest.js';
28
+ /** Structured drift entry. `where` is the named source impl ('a' or 'b'). */
29
+ export type ActionManifestDiff = {
30
+ readonly kind: 'method_only_in';
31
+ readonly where: 'a' | 'b';
32
+ readonly method: string;
33
+ } | {
34
+ readonly kind: 'side_effects_differ';
35
+ readonly method: string;
36
+ readonly a: boolean;
37
+ readonly b: boolean;
38
+ } | {
39
+ readonly kind: 'auth_field_differs';
40
+ readonly method: string;
41
+ readonly field: 'account' | 'actor' | 'roles' | 'credential_types';
42
+ readonly a: unknown;
43
+ readonly b: unknown;
44
+ };
45
+ /**
46
+ * Structural diff between two manifests — empty array means parity holds.
47
+ *
48
+ * Order is deterministic: methods in sorted order, with each method's
49
+ * side-effect + auth-field sub-diffs grouped together.
50
+ */
51
+ export declare const diff_action_manifests: (a: ActionManifest, b: ActionManifest) => Array<ActionManifestDiff>;
52
+ /** Labels used in formatted output — defaults to `'a'` and `'b'`. */
53
+ export interface ActionManifestDiffLabels {
54
+ readonly a?: string;
55
+ readonly b?: string;
56
+ }
57
+ /**
58
+ * Render a diff list as a human-readable multi-line string. Empty diffs
59
+ * produce an empty string.
60
+ */
61
+ export declare const format_action_manifest_diffs: (diffs: ReadonlyArray<ActionManifestDiff>, labels?: ActionManifestDiffLabels) => string;
62
+ /**
63
+ * Throw if the two manifests disagree. The error message names the impls
64
+ * (via `labels`) and lists every diff, so the failure is self-diagnosing.
65
+ */
66
+ export declare const assert_action_manifests_equal: (a: ActionManifest, b: ActionManifest, labels?: ActionManifestDiffLabels) => void;
67
+ //# sourceMappingURL=action_manifest_parity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action_manifest_parity.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/action_manifest_parity.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAE9B;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,EAAC,cAAc,EAAsB,MAAM,sBAAsB,CAAC;AAW9E,6EAA6E;AAC7E,MAAM,MAAM,kBAAkB,GAC3B;IAAC,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,GAAG,GAAG,GAAG,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAC,GACrF;IACA,QAAQ,CAAC,IAAI,EAAE,qBAAqB,CAAC;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC;CACnB,GACD;IACA,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,kBAAkB,CAAC;IACnE,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAML;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,GACjC,GAAG,cAAc,EACjB,GAAG,cAAc,KACf,KAAK,CAAC,kBAAkB,CA+B1B,CAAC;AAEF,qEAAqE;AACrE,MAAM,WAAW,wBAAwB;IACxC,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,eAAO,MAAM,4BAA4B,GACxC,OAAO,aAAa,CAAC,kBAAkB,CAAC,EACxC,SAAQ,wBAA6B,KACnC,MA4BF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,6BAA6B,GACzC,GAAG,cAAc,EACjB,GAAG,cAAc,EACjB,SAAQ,wBAA6B,KACnC,IAQF,CAAC"}