@fuzdev/fuz_app 0.68.0 → 0.69.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 (95) hide show
  1. package/dist/actions/perform_action.d.ts.map +1 -1
  2. package/dist/actions/perform_action.js +10 -3
  3. package/dist/auth/admin_action_specs.d.ts +2 -3
  4. package/dist/auth/admin_action_specs.d.ts.map +1 -1
  5. package/dist/auth/admin_action_specs.js +2 -3
  6. package/dist/auth/admin_actions.d.ts +4 -14
  7. package/dist/auth/admin_actions.d.ts.map +1 -1
  8. package/dist/auth/admin_actions.js +28 -36
  9. package/dist/auth/signup_routes.d.ts +0 -3
  10. package/dist/auth/signup_routes.d.ts.map +1 -1
  11. package/dist/auth/signup_routes.js +9 -3
  12. package/dist/auth/standard_rpc_actions.d.ts +5 -5
  13. package/dist/auth/standard_rpc_actions.js +4 -4
  14. package/dist/server/app_server.d.ts +1 -7
  15. package/dist/server/app_server.d.ts.map +1 -1
  16. package/dist/server/app_server.js +1 -5
  17. package/dist/testing/CLAUDE.md +85 -2
  18. package/dist/testing/app_server.d.ts +34 -0
  19. package/dist/testing/app_server.d.ts.map +1 -1
  20. package/dist/testing/app_server.js +31 -6
  21. package/dist/testing/cross_backend/account_lifecycle.d.ts.map +1 -1
  22. package/dist/testing/cross_backend/account_lifecycle.js +69 -1
  23. package/dist/testing/cross_backend/actor_lookup.d.ts +10 -0
  24. package/dist/testing/cross_backend/actor_lookup.d.ts.map +1 -0
  25. package/dist/testing/cross_backend/actor_lookup.js +83 -0
  26. package/dist/testing/cross_backend/actor_search.d.ts +6 -0
  27. package/dist/testing/cross_backend/actor_search.d.ts.map +1 -0
  28. package/dist/testing/cross_backend/actor_search.js +92 -0
  29. package/dist/testing/cross_backend/app_settings.d.ts +6 -0
  30. package/dist/testing/cross_backend/app_settings.d.ts.map +1 -0
  31. package/dist/testing/cross_backend/app_settings.js +95 -0
  32. package/dist/testing/cross_backend/backend_config.d.ts +1 -1
  33. package/dist/testing/cross_backend/capabilities.d.ts +0 -9
  34. package/dist/testing/cross_backend/capabilities.d.ts.map +1 -1
  35. package/dist/testing/cross_backend/capabilities.js +0 -1
  36. package/dist/testing/cross_backend/cell_grant_role.d.ts +8 -0
  37. package/dist/testing/cross_backend/cell_grant_role.d.ts.map +1 -0
  38. package/dist/testing/cross_backend/cell_grant_role.js +102 -0
  39. package/dist/testing/cross_backend/conformance_case.d.ts +144 -0
  40. package/dist/testing/cross_backend/conformance_case.d.ts.map +1 -0
  41. package/dist/testing/cross_backend/conformance_case.js +132 -0
  42. package/dist/testing/cross_backend/conformance_table.d.ts +46 -0
  43. package/dist/testing/cross_backend/conformance_table.d.ts.map +1 -0
  44. package/dist/testing/cross_backend/conformance_table.js +199 -0
  45. package/dist/testing/cross_backend/default_backend_configs.d.ts.map +1 -1
  46. package/dist/testing/cross_backend/default_backend_configs.js +0 -2
  47. package/dist/testing/cross_backend/default_spine_surface.d.ts +17 -9
  48. package/dist/testing/cross_backend/default_spine_surface.d.ts.map +1 -1
  49. package/dist/testing/cross_backend/default_spine_surface.js +20 -12
  50. package/dist/testing/cross_backend/origin.d.ts +10 -0
  51. package/dist/testing/cross_backend/origin.d.ts.map +1 -0
  52. package/dist/testing/cross_backend/origin.js +73 -0
  53. package/dist/testing/cross_backend/setup.d.ts +22 -40
  54. package/dist/testing/cross_backend/setup.d.ts.map +1 -1
  55. package/dist/testing/cross_backend/setup.js +34 -5
  56. package/dist/testing/cross_backend/testing_reset_actions.d.ts +90 -2
  57. package/dist/testing/cross_backend/testing_reset_actions.d.ts.map +1 -1
  58. package/dist/testing/cross_backend/testing_reset_actions.js +91 -3
  59. package/dist/testing/cross_backend/xfail.d.ts +15 -0
  60. package/dist/testing/cross_backend/xfail.d.ts.map +1 -0
  61. package/dist/testing/cross_backend/xfail.js +37 -0
  62. package/dist/testing/integration.d.ts +2 -3
  63. package/dist/testing/integration.d.ts.map +1 -1
  64. package/dist/testing/integration.js +20 -85
  65. package/dist/testing/rate_limiting.d.ts +1 -1
  66. package/dist/testing/rpc_helpers.d.ts +3 -3
  67. package/dist/testing/sse_round_trip.d.ts +1 -1
  68. package/dist/testing/stubs.d.ts.map +1 -1
  69. package/dist/testing/stubs.js +0 -1
  70. package/dist/ui/AdminAccounts.svelte +74 -83
  71. package/dist/ui/AdminAccounts.svelte.d.ts.map +1 -1
  72. package/dist/ui/AdminSessions.svelte +21 -23
  73. package/dist/ui/AdminSessions.svelte.d.ts.map +1 -1
  74. package/dist/ui/CLAUDE.md +17 -26
  75. package/dist/ui/OpenSignupToggle.svelte +2 -5
  76. package/dist/ui/OpenSignupToggle.svelte.d.ts.map +1 -1
  77. package/dist/ui/account_sessions_state.svelte.d.ts +9 -10
  78. package/dist/ui/account_sessions_state.svelte.d.ts.map +1 -1
  79. package/dist/ui/account_sessions_state.svelte.js +7 -17
  80. package/dist/ui/admin_accounts_state.svelte.d.ts +12 -19
  81. package/dist/ui/admin_accounts_state.svelte.d.ts.map +1 -1
  82. package/dist/ui/admin_accounts_state.svelte.js +10 -24
  83. package/dist/ui/admin_invites_state.svelte.d.ts +8 -11
  84. package/dist/ui/admin_invites_state.svelte.d.ts.map +1 -1
  85. package/dist/ui/admin_invites_state.svelte.js +7 -16
  86. package/dist/ui/admin_sessions_state.svelte.d.ts +6 -10
  87. package/dist/ui/admin_sessions_state.svelte.d.ts.map +1 -1
  88. package/dist/ui/admin_sessions_state.svelte.js +4 -14
  89. package/dist/ui/app_settings_state.svelte.d.ts +8 -12
  90. package/dist/ui/app_settings_state.svelte.d.ts.map +1 -1
  91. package/dist/ui/app_settings_state.svelte.js +6 -16
  92. package/dist/ui/audit_log_state.svelte.d.ts +9 -8
  93. package/dist/ui/audit_log_state.svelte.d.ts.map +1 -1
  94. package/dist/ui/audit_log_state.svelte.js +8 -20
  95. package/package.json +1 -1
@@ -0,0 +1,102 @@
1
+ import '../assert_dev_env.js';
2
+ /**
3
+ * Cross-backend parity suite for **role-shaped** `cell_grant`s.
4
+ *
5
+ * The cell CRUD / relations suites exercise only actor-shaped grant
6
+ * principals. This suite covers the role-shaped path and its closed-registry
7
+ * gate — the security-correctness property that the Rust spine previously
8
+ * lacked (it created inert grant rows for any role string). Both spines now
9
+ * validate the role against a closed registry at create.
10
+ *
11
+ * - **role grant admits a holder; excludes a non-holder** — an owner grants
12
+ * `{role}` on a private cell; an account holding that role can `cell_get`
13
+ * it (200), an account without it gets the IDOR-mask 404.
14
+ * - **unknown role rejected at create (security-correctness)** — granting a
15
+ * role outside the registry is `invalid_params` / `cell_grant_unknown_role`,
16
+ * not a silent inert row.
17
+ * - **editor-level role grant admits edit** — a holder of an `editor`-level
18
+ * role grant can `cell_update` the cell's content.
19
+ *
20
+ * The holder is seeded via `extra_accounts` under `CELL_ROLE_HOLDER_USERNAME`
21
+ * holding `CELL_EDITOR_ROLE` (the role has no grant path, so it can't be
22
+ * offered — the bootstrap-cradle seed is the only path). Both legs configure
23
+ * that seed and register `CELL_EDITOR_ROLE` in their role registry; the Rust
24
+ * `testing_spine_stub` mirrors the same membership in its `known_roles`.
25
+ *
26
+ * Cites `security.md` §Authorization (role-shaped cell-grant validation).
27
+ * Runs both legs via the shared `{setup_test}` protocol: in-process
28
+ * (`auth/cell_grant_role_parity.db.test.ts`) + cross-process
29
+ * (`cross_backend/cell_grant_role.cross.test.ts`). Gated on
30
+ * `capabilities.cell_relations` (true on every spine, so it never skips).
31
+ *
32
+ * `$lib`-free by contract (relative specifiers only).
33
+ *
34
+ * @module
35
+ */
36
+ import { describe, assert } from 'vitest';
37
+ import { CellCreateOutput, CellGetOutput, CellUpdateOutput } from '../../auth/cell_action_specs.js';
38
+ import { CellGrantCreateOutput, ERROR_CELL_GRANT_UNKNOWN_ROLE, } from '../../auth/cell_grant_action_specs.js';
39
+ import { test_if } from './capabilities.js';
40
+ import { cross_rpc_call, error_reason, expect_output, } from './cell_cross_helpers.js';
41
+ import { SPINE_CELL_EDITOR_ROLE, SPINE_RPC_PATH } from './default_spine_surface.js';
42
+ /** App role the holder is seeded with; matches the spine's registered role. */
43
+ export const CELL_EDITOR_ROLE = SPINE_CELL_EDITOR_ROLE;
44
+ /** Username the fixture seeds (via `extra_accounts`) holding `CELL_EDITOR_ROLE`. */
45
+ export const CELL_ROLE_HOLDER_USERNAME = 'cell_role_holder';
46
+ /** A role string deliberately absent from the registry. */
47
+ const UNREGISTERED_ROLE = 'not_a_registered_role';
48
+ export const describe_cell_grant_role_cross_tests = (options) => {
49
+ const { setup_test, capabilities } = options;
50
+ const rpc_path = options.rpc_path ?? SPINE_RPC_PATH;
51
+ describe('cell_grant role-shaped parity', () => {
52
+ test_if(capabilities.cell_relations, 'role grant admits a holder of the role and excludes a non-holder', async () => {
53
+ const fixture = await setup_test();
54
+ const t = fixture.transport;
55
+ const owner = await fixture.create_account({ username: 'cell_role_owner' });
56
+ const owner_h = owner.create_session_headers();
57
+ const holder = fixture.extra_accounts[CELL_ROLE_HOLDER_USERNAME];
58
+ assert.ok(holder, `fixture must seed the ${CELL_ROLE_HOLDER_USERNAME} extra account`);
59
+ const stranger = await fixture.create_account({ username: 'cell_role_stranger' });
60
+ // Owner creates a private cell (default visibility) and grants
61
+ // view access to anyone holding CELL_EDITOR_ROLE.
62
+ const created = expect_output(await cross_rpc_call(t, rpc_path, 'cell_create', { data: { kind: 'note' } }, owner_h), CellCreateOutput);
63
+ const cell_id = created.cell.id;
64
+ expect_output(await cross_rpc_call(t, rpc_path, 'cell_grant_create', { cell_id, level: 'viewer', principal: { kind: 'role', role: CELL_EDITOR_ROLE } }, owner_h), CellGrantCreateOutput);
65
+ // Holder of the role is admitted through the role-shaped grant.
66
+ const holder_view = expect_output(await cross_rpc_call(t, rpc_path, 'cell_get', { id: cell_id }, holder.create_session_headers()), CellGetOutput);
67
+ assert.strictEqual(holder_view.cell.id, cell_id, 'holder sees the granted cell');
68
+ // A non-holder sees the IDOR-mask 404 — the grant keys on the role,
69
+ // not mere authentication.
70
+ const stranger_view = await cross_rpc_call(t, rpc_path, 'cell_get', { id: cell_id }, stranger.create_session_headers());
71
+ assert.ok(!stranger_view.ok, 'non-holder must not see the cell');
72
+ assert.strictEqual(error_reason(stranger_view), 'cell_not_found');
73
+ });
74
+ test_if(capabilities.cell_relations, 'role-shaped grant for an unregistered role is rejected at create', async () => {
75
+ const fixture = await setup_test();
76
+ const t = fixture.transport;
77
+ const owner = await fixture.create_account({ username: 'cell_unknown_role_owner' });
78
+ const owner_h = owner.create_session_headers();
79
+ const created = expect_output(await cross_rpc_call(t, rpc_path, 'cell_create', { data: { kind: 'note' } }, owner_h), CellCreateOutput);
80
+ const denied = await cross_rpc_call(t, rpc_path, 'cell_grant_create', {
81
+ cell_id: created.cell.id,
82
+ level: 'viewer',
83
+ principal: { kind: 'role', role: UNREGISTERED_ROLE },
84
+ }, owner_h);
85
+ assert.ok(!denied.ok, 'granting an unregistered role must fail');
86
+ assert.strictEqual(error_reason(denied), ERROR_CELL_GRANT_UNKNOWN_ROLE);
87
+ });
88
+ test_if(capabilities.cell_relations, 'editor-level role grant admits content edit', async () => {
89
+ const fixture = await setup_test();
90
+ const t = fixture.transport;
91
+ const owner = await fixture.create_account({ username: 'cell_role_edit_owner' });
92
+ const owner_h = owner.create_session_headers();
93
+ const holder = fixture.extra_accounts[CELL_ROLE_HOLDER_USERNAME];
94
+ assert.ok(holder, `fixture must seed the ${CELL_ROLE_HOLDER_USERNAME} extra account`);
95
+ const created = expect_output(await cross_rpc_call(t, rpc_path, 'cell_create', { data: { kind: 'note' } }, owner_h), CellCreateOutput);
96
+ const cell_id = created.cell.id;
97
+ expect_output(await cross_rpc_call(t, rpc_path, 'cell_grant_create', { cell_id, level: 'editor', principal: { kind: 'role', role: CELL_EDITOR_ROLE } }, owner_h), CellGrantCreateOutput);
98
+ const edited = expect_output(await cross_rpc_call(t, rpc_path, 'cell_update', { cell_id, data: { kind: 'note', label: 'by role editor' } }, holder.create_session_headers()), CellUpdateOutput);
99
+ assert.strictEqual(edited.cell.updated_by, holder.actor.id, 'edit attributed to the holder');
100
+ });
101
+ });
102
+ };
@@ -0,0 +1,144 @@
1
+ import '../assert_dev_env.js';
2
+ /**
3
+ * Declarative conformance-case schema for the cross-backend behavioral +
4
+ * security suite.
5
+ *
6
+ * A conformance case is a single request → expected-response assertion,
7
+ * carried as **data**. The case references a `method` (an RPC method name
8
+ * or a REST auth-route suffix); the runner
9
+ * (`describe_conformance_table_tests`) resolves the `input` / `output`
10
+ * Zod schemas from the live action-spec registry / `RouteSpec` — the case
11
+ * never carries a schema. This is the opinionated behavioral/security
12
+ * layer on top of the spec-derived auto-enumeration
13
+ * (`describe_rpc_round_trip_tests` / `describe_rpc_attack_surface_tests`):
14
+ * the same case definition runs in-process (fast, every `gro test`) and
15
+ * cross-process (the conformance gate) against each impl's real auth
16
+ * resolution.
17
+ *
18
+ * The table is for single-request matrices (credential-type ceiling,
19
+ * privilege gates, IDOR masks, enumeration-equivalence, validation).
20
+ * Multi-step flows stay imperative in their own `describe_*` suites,
21
+ * sharing assertion primitives — there is deliberately no declarative
22
+ * setup DSL.
23
+ *
24
+ * @module
25
+ */
26
+ import { z } from 'zod';
27
+ /**
28
+ * Closed enum of fixture-provisioned principals a case runs `as`. Each
29
+ * value maps to a `TestFixture` accessor (or a seeded `extra_accounts`
30
+ * entry) in the runner's `resolve_principal` — there is **no** inline
31
+ * credential minting in a case (that would be the setup-DSL trap).
32
+ *
33
+ * - `keeper` — the per-test bootstrapped keeper (holds `ROLE_KEEPER` +
34
+ * `ROLE_ADMIN`), session credential.
35
+ * - `daemon` — the keeper authenticated via the daemon-token header.
36
+ * - `token` — the keeper authenticated via a bearer api-token (non-browser
37
+ * context; the runner suppresses `Origin` so the token isn't discarded).
38
+ * - `anonymous` — no credential, fresh cookie jar.
39
+ * - `fresh_non_admin` — a freshly minted account with no roles, session
40
+ * credential (via the production invite → signup → login flow).
41
+ * - `role_holder` — a seeded `extra_accounts` principal holding a specific
42
+ * role; the runner reads it by the username named in
43
+ * `ConformanceTableOptions.principals.role_holder`.
44
+ * - `wrong_role` — a seeded `extra_accounts` principal holding a role
45
+ * other than the one a route requires; named via
46
+ * `ConformanceTableOptions.principals.wrong_role`.
47
+ * - `expired_session` — the keeper account presented via an *expired
48
+ * server-side session* cookie (minted by `fixture.mint_expired_session()`:
49
+ * a backdated `auth_session` row behind a still-valid signed cookie
50
+ * payload, so the authoritative DB-row expiry gate is what refuses it).
51
+ */
52
+ export declare const ConformancePrincipal: z.ZodEnum<{
53
+ keeper: "keeper";
54
+ token: "token";
55
+ daemon: "daemon";
56
+ anonymous: "anonymous";
57
+ fresh_non_admin: "fresh_non_admin";
58
+ role_holder: "role_holder";
59
+ wrong_role: "wrong_role";
60
+ expired_session: "expired_session";
61
+ }>;
62
+ export type ConformancePrincipal = z.infer<typeof ConformancePrincipal>;
63
+ /** The request a conformance case issues. */
64
+ export declare const ConformanceCaseRequest: z.ZodObject<{
65
+ method: z.ZodString;
66
+ params: z.ZodOptional<z.ZodUnknown>;
67
+ as: z.ZodEnum<{
68
+ keeper: "keeper";
69
+ token: "token";
70
+ daemon: "daemon";
71
+ anonymous: "anonymous";
72
+ fresh_non_admin: "fresh_non_admin";
73
+ role_holder: "role_holder";
74
+ wrong_role: "wrong_role";
75
+ expired_session: "expired_session";
76
+ }>;
77
+ verb: z.ZodOptional<z.ZodEnum<{
78
+ GET: "GET";
79
+ POST: "POST";
80
+ }>>;
81
+ }, z.core.$strict>;
82
+ export type ConformanceCaseRequest = z.infer<typeof ConformanceCaseRequest>;
83
+ /** The expected response shape a conformance case asserts. */
84
+ export declare const ConformanceCaseExpectation: z.ZodObject<{
85
+ status: z.ZodNumber;
86
+ error_reason: z.ZodOptional<z.ZodString>;
87
+ fields: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
88
+ }, z.core.$strict>;
89
+ export type ConformanceCaseExpectation = z.infer<typeof ConformanceCaseExpectation>;
90
+ /**
91
+ * Marks a case as a deferred-by-design gap. The runner routes it through
92
+ * `xfail_until` instead of a normal `test` — visible (distinct from pass)
93
+ * and self-cleaning (flips red when the impl starts passing, forcing the
94
+ * marker's removal). Use for declared gaps (e.g. facts), never for
95
+ * in-scope gaps (those fail loud as a red `test`).
96
+ */
97
+ export declare const ConformanceCaseXfail: z.ZodObject<{
98
+ tracking_id: z.ZodString;
99
+ reason: z.ZodString;
100
+ }, z.core.$strict>;
101
+ export type ConformanceCaseXfail = z.infer<typeof ConformanceCaseXfail>;
102
+ /**
103
+ * A single conformance case. `name` is the assertion; the optional
104
+ * free-text `note` is printed in the test label / failure output. A
105
+ * security case's `note` should reference a **public** fuz_app doc
106
+ * property (`security.md` / `architecture.md` / module TSDoc), since the
107
+ * table ships in a public package — not an internal planning doc. The note
108
+ * is documentation, not a gate: it stays free-text by design because a
109
+ * non-empty-string check never catches a *wrong* citation — the citation
110
+ * is verified in review.
111
+ */
112
+ export declare const ConformanceCase: z.ZodObject<{
113
+ name: z.ZodString;
114
+ request: z.ZodObject<{
115
+ method: z.ZodString;
116
+ params: z.ZodOptional<z.ZodUnknown>;
117
+ as: z.ZodEnum<{
118
+ keeper: "keeper";
119
+ token: "token";
120
+ daemon: "daemon";
121
+ anonymous: "anonymous";
122
+ fresh_non_admin: "fresh_non_admin";
123
+ role_holder: "role_holder";
124
+ wrong_role: "wrong_role";
125
+ expired_session: "expired_session";
126
+ }>;
127
+ verb: z.ZodOptional<z.ZodEnum<{
128
+ GET: "GET";
129
+ POST: "POST";
130
+ }>>;
131
+ }, z.core.$strict>;
132
+ expect: z.ZodObject<{
133
+ status: z.ZodNumber;
134
+ error_reason: z.ZodOptional<z.ZodString>;
135
+ fields: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
136
+ }, z.core.$strict>;
137
+ note: z.ZodOptional<z.ZodString>;
138
+ xfail: z.ZodOptional<z.ZodObject<{
139
+ tracking_id: z.ZodString;
140
+ reason: z.ZodString;
141
+ }, z.core.$strict>>;
142
+ }, z.core.$strict>;
143
+ export type ConformanceCase = z.infer<typeof ConformanceCase>;
144
+ //# sourceMappingURL=conformance_case.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conformance_case.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/conformance_case.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAE9B;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAEtB;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;EAS/B,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAExE,6CAA6C;AAC7C,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;kBAgBjC,CAAC;AACH,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAE5E,8DAA8D;AAC9D,eAAO,MAAM,0BAA0B;;;;kBAqBrC,CAAC;AACH,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAEpF;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB;;;kBAK/B,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAExE;;;;;;;;;GASG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAS1B,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC"}
@@ -0,0 +1,132 @@
1
+ import '../assert_dev_env.js';
2
+ /**
3
+ * Declarative conformance-case schema for the cross-backend behavioral +
4
+ * security suite.
5
+ *
6
+ * A conformance case is a single request → expected-response assertion,
7
+ * carried as **data**. The case references a `method` (an RPC method name
8
+ * or a REST auth-route suffix); the runner
9
+ * (`describe_conformance_table_tests`) resolves the `input` / `output`
10
+ * Zod schemas from the live action-spec registry / `RouteSpec` — the case
11
+ * never carries a schema. This is the opinionated behavioral/security
12
+ * layer on top of the spec-derived auto-enumeration
13
+ * (`describe_rpc_round_trip_tests` / `describe_rpc_attack_surface_tests`):
14
+ * the same case definition runs in-process (fast, every `gro test`) and
15
+ * cross-process (the conformance gate) against each impl's real auth
16
+ * resolution.
17
+ *
18
+ * The table is for single-request matrices (credential-type ceiling,
19
+ * privilege gates, IDOR masks, enumeration-equivalence, validation).
20
+ * Multi-step flows stay imperative in their own `describe_*` suites,
21
+ * sharing assertion primitives — there is deliberately no declarative
22
+ * setup DSL.
23
+ *
24
+ * @module
25
+ */
26
+ import { z } from 'zod';
27
+ /**
28
+ * Closed enum of fixture-provisioned principals a case runs `as`. Each
29
+ * value maps to a `TestFixture` accessor (or a seeded `extra_accounts`
30
+ * entry) in the runner's `resolve_principal` — there is **no** inline
31
+ * credential minting in a case (that would be the setup-DSL trap).
32
+ *
33
+ * - `keeper` — the per-test bootstrapped keeper (holds `ROLE_KEEPER` +
34
+ * `ROLE_ADMIN`), session credential.
35
+ * - `daemon` — the keeper authenticated via the daemon-token header.
36
+ * - `token` — the keeper authenticated via a bearer api-token (non-browser
37
+ * context; the runner suppresses `Origin` so the token isn't discarded).
38
+ * - `anonymous` — no credential, fresh cookie jar.
39
+ * - `fresh_non_admin` — a freshly minted account with no roles, session
40
+ * credential (via the production invite → signup → login flow).
41
+ * - `role_holder` — a seeded `extra_accounts` principal holding a specific
42
+ * role; the runner reads it by the username named in
43
+ * `ConformanceTableOptions.principals.role_holder`.
44
+ * - `wrong_role` — a seeded `extra_accounts` principal holding a role
45
+ * other than the one a route requires; named via
46
+ * `ConformanceTableOptions.principals.wrong_role`.
47
+ * - `expired_session` — the keeper account presented via an *expired
48
+ * server-side session* cookie (minted by `fixture.mint_expired_session()`:
49
+ * a backdated `auth_session` row behind a still-valid signed cookie
50
+ * payload, so the authoritative DB-row expiry gate is what refuses it).
51
+ */
52
+ export const ConformancePrincipal = z.enum([
53
+ 'keeper',
54
+ 'daemon',
55
+ 'token',
56
+ 'anonymous',
57
+ 'fresh_non_admin',
58
+ 'role_holder',
59
+ 'wrong_role',
60
+ 'expired_session',
61
+ ]);
62
+ /** The request a conformance case issues. */
63
+ export const ConformanceCaseRequest = z.strictObject({
64
+ method: z.string().meta({
65
+ description: 'RPC method name (e.g. `admin_account_list`) or a REST auth-route suffix ' +
66
+ '(e.g. `/login`). A leading `/` selects the REST branch; otherwise the ' +
67
+ 'runner resolves the RPC action from the spec registry.',
68
+ }),
69
+ params: z
70
+ .unknown()
71
+ .optional()
72
+ .meta({ description: 'Request params / body. Omit for nullary methods.' }),
73
+ as: ConformancePrincipal,
74
+ verb: z
75
+ .enum(['POST', 'GET'])
76
+ .optional()
77
+ .meta({ description: 'HTTP verb. Defaults to POST; use GET for `side_effects: false` reads.' }),
78
+ });
79
+ /** The expected response shape a conformance case asserts. */
80
+ export const ConformanceCaseExpectation = z.strictObject({
81
+ status: z.number().int().meta({ description: 'Expected HTTP status code.' }),
82
+ error_reason: z
83
+ .string()
84
+ .optional()
85
+ .meta({
86
+ description: 'Expected error reason — pass the IMPORTED `ERROR_*` constant from ' +
87
+ '`http/error_schemas.ts`, never a string literal. Asserted against the RPC ' +
88
+ '`error.data.reason` (when the denial carries one) or the REST flat-body ' +
89
+ '`error` field. The pre-validation 401 carries `data.reason` too; a denial ' +
90
+ 'that genuinely omits it falls back to the `status` assertion to pin the class.',
91
+ }),
92
+ fields: z
93
+ .record(z.string(), z.unknown())
94
+ .optional()
95
+ .meta({
96
+ description: 'Specific field-value assertions on the success `result` (2xx) or the error ' +
97
+ '`error.data` (non-2xx). Each key must deep-equal the corresponding response field.',
98
+ }),
99
+ });
100
+ /**
101
+ * Marks a case as a deferred-by-design gap. The runner routes it through
102
+ * `xfail_until` instead of a normal `test` — visible (distinct from pass)
103
+ * and self-cleaning (flips red when the impl starts passing, forcing the
104
+ * marker's removal). Use for declared gaps (e.g. facts), never for
105
+ * in-scope gaps (those fail loud as a red `test`).
106
+ */
107
+ export const ConformanceCaseXfail = z.strictObject({
108
+ tracking_id: z
109
+ .string()
110
+ .meta({ description: 'Tracking id for the deferred gap (issue id or tracking slug).' }),
111
+ reason: z.string().meta({ description: 'Why this case is deferred-by-design.' }),
112
+ });
113
+ /**
114
+ * A single conformance case. `name` is the assertion; the optional
115
+ * free-text `note` is printed in the test label / failure output. A
116
+ * security case's `note` should reference a **public** fuz_app doc
117
+ * property (`security.md` / `architecture.md` / module TSDoc), since the
118
+ * table ships in a public package — not an internal planning doc. The note
119
+ * is documentation, not a gate: it stays free-text by design because a
120
+ * non-empty-string check never catches a *wrong* citation — the citation
121
+ * is verified in review.
122
+ */
123
+ export const ConformanceCase = z.strictObject({
124
+ name: z.string().meta({ description: 'The assertion, used as the test label.' }),
125
+ request: ConformanceCaseRequest,
126
+ expect: ConformanceCaseExpectation,
127
+ note: z
128
+ .string()
129
+ .optional()
130
+ .meta({ description: 'Free-text note printed in the label / failure output.' }),
131
+ xfail: ConformanceCaseXfail.optional(),
132
+ });
@@ -0,0 +1,46 @@
1
+ import '../assert_dev_env.js';
2
+ import type { AppSurfaceSpec } from '../../http/surface.js';
3
+ import type { SessionOptions } from '../../auth/session_cookie.js';
4
+ import { type RpcEndpointsSuiteOption } from '../rpc_helpers.js';
5
+ import { type ConformanceCase } from './conformance_case.js';
6
+ import type { BackendCapabilities } from './capabilities.js';
7
+ import type { SetupTest } from './setup.js';
8
+ /**
9
+ * Names a seeded `extra_accounts` username for the `role_holder` /
10
+ * `wrong_role` principals — the only two that aren't backed by an
11
+ * always-available fixture accessor. Suites exercising those principals
12
+ * declare the matching `extra_accounts` at setup and name them here.
13
+ */
14
+ export interface ConformancePrincipalConfig {
15
+ /** `extra_accounts` username for the `role_holder` principal. */
16
+ readonly role_holder?: string;
17
+ /** `extra_accounts` username for the `wrong_role` principal. */
18
+ readonly wrong_role?: string;
19
+ }
20
+ /** Options for `describe_conformance_table_tests`. */
21
+ export interface ConformanceTableOptions {
22
+ /** The conformance cases to run, in order. */
23
+ readonly cases: ReadonlyArray<ConformanceCase>;
24
+ /** Per-test fixture producer (in-process or cross-process). */
25
+ readonly setup_test: SetupTest;
26
+ /** Surface spec — supplies the `RouteSpec`s for the REST branch. */
27
+ readonly surface_source: AppSurfaceSpec;
28
+ /** Declared backend capabilities (reserved for capability-gated rows). */
29
+ readonly capabilities: BackendCapabilities;
30
+ /** RPC endpoints — resolved to find each method's action spec. */
31
+ readonly rpc_endpoints: RpcEndpointsSuiteOption;
32
+ /** Session options — needed to resolve the `rpc_endpoints` factory form. */
33
+ readonly session_options: SessionOptions<string>;
34
+ /** Maps the `role_holder` / `wrong_role` principals to seeded usernames. */
35
+ readonly principals?: ConformancePrincipalConfig;
36
+ /** `describe` block label. Defaults to `'conformance table'`. */
37
+ readonly suite_name?: string;
38
+ }
39
+ /**
40
+ * Register a `describe` block running every `ConformanceCase` as a
41
+ * vitest `test` (or `xfail_until` for deferred-by-design rows). Drives
42
+ * either transport via the shared `{setup_test, surface_source,
43
+ * capabilities}` protocol.
44
+ */
45
+ export declare const describe_conformance_table_tests: (options: ConformanceTableOptions) => void;
46
+ //# sourceMappingURL=conformance_table.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conformance_table.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/conformance_table.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAwB9B,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,uBAAuB,CAAC;AAE1D,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,8BAA8B,CAAC;AAMjE,OAAO,EAIN,KAAK,uBAAuB,EAC5B,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAC,KAAK,eAAe,EAA4B,MAAM,uBAAuB,CAAC;AACtF,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,mBAAmB,CAAC;AAC3D,OAAO,KAAK,EAAC,SAAS,EAAc,MAAM,YAAY,CAAC;AAGvD;;;;;GAKG;AACH,MAAM,WAAW,0BAA0B;IAC1C,iEAAiE;IACjE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,gEAAgE;IAChE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,sDAAsD;AACtD,MAAM,WAAW,uBAAuB;IACvC,8CAA8C;IAC9C,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IAC/C,+DAA+D;IAC/D,QAAQ,CAAC,UAAU,EAAE,SAAS,CAAC;IAC/B,oEAAoE;IACpE,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;IACxC,0EAA0E;IAC1E,QAAQ,CAAC,YAAY,EAAE,mBAAmB,CAAC;IAC3C,kEAAkE;IAClE,QAAQ,CAAC,aAAa,EAAE,uBAAuB,CAAC;IAChD,4EAA4E;IAC5E,QAAQ,CAAC,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACjD,4EAA4E;IAC5E,QAAQ,CAAC,UAAU,CAAC,EAAE,0BAA0B,CAAC;IACjD,iEAAiE;IACjE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC7B;AAgOD;;;;;GAKG;AACH,eAAO,MAAM,gCAAgC,GAAI,SAAS,uBAAuB,KAAG,IAgBnF,CAAC"}
@@ -0,0 +1,199 @@
1
+ import '../assert_dev_env.js';
2
+ /**
3
+ * Table runner for the declarative cross-backend conformance suite.
4
+ *
5
+ * `describe_conformance_table_tests` takes a list of `ConformanceCase`
6
+ * rows plus the standard `{setup_test, surface_source, capabilities}`
7
+ * fixture protocol every Tier 1 suite uses — so **one runner drives both
8
+ * transports**: in-process via `default_in_process_setup` (fast, every
9
+ * `gro test`) and cross-process via `default_cross_process_setup` (the
10
+ * conformance gate, exercising each impl's real auth resolution over real
11
+ * HTTP). Same case definition, transport-parameterized.
12
+ *
13
+ * Each row references a `method`; the runner resolves its `input` /
14
+ * `output` schema from the live spec registry (RPC) or `RouteSpec` (the 6
15
+ * REST auth routes) — the row never carries a schema. The principal the
16
+ * row runs `as` resolves to a `TestFixture` accessor via
17
+ * `resolve_principal` — no inline credential minting.
18
+ *
19
+ * @module
20
+ */
21
+ import { assert, describe, test } from 'vitest';
22
+ import { find_auth_route, rest_auth_route_suffixes, } from '../integration_helpers.js';
23
+ import { find_rpc_action, rpc_call, resolve_rpc_endpoints_for_setup, } from '../rpc_helpers.js';
24
+ import {} from './conformance_case.js';
25
+ import { xfail_until } from './xfail.js';
26
+ /**
27
+ * Map a `ConformancePrincipal` onto the transport + headers it
28
+ * authenticates with, reading exclusively from the per-test `TestFixture`.
29
+ *
30
+ * The five always-available principals resolve from fixture accessors;
31
+ * `role_holder` / `wrong_role` read a seeded `extra_accounts` entry named
32
+ * via `options.principals` (throws a clear setup error when unconfigured).
33
+ */
34
+ const resolve_principal = async (fixture, as, principals) => {
35
+ switch (as) {
36
+ case 'keeper':
37
+ // Keeper carries its session cookie via `create_session_headers`
38
+ // (in-process the transport is stateless; cross-process the jar
39
+ // also holds it — the explicit header is the same value).
40
+ return { transport: fixture.transport, headers: fixture.create_session_headers() };
41
+ case 'daemon':
42
+ // Daemon-token is a non-browser credential — empty jar + no Origin.
43
+ return {
44
+ transport: fixture.fresh_transport({ origin: null }),
45
+ headers: fixture.create_daemon_token_headers(),
46
+ suppress_default_origin: true,
47
+ };
48
+ case 'token':
49
+ // Bearer is discarded in a browser context — empty jar + no Origin.
50
+ return {
51
+ transport: fixture.fresh_transport({ origin: null }),
52
+ headers: fixture.create_bearer_headers(),
53
+ suppress_default_origin: true,
54
+ };
55
+ case 'anonymous':
56
+ // Fresh jar so the keeper cookie (cross-process) can't leak in.
57
+ return { transport: fixture.fresh_transport(), headers: {} };
58
+ case 'fresh_non_admin': {
59
+ const account = await fixture.create_account();
60
+ return { transport: fixture.fresh_transport(), headers: account.create_session_headers() };
61
+ }
62
+ case 'expired_session': {
63
+ // The keeper presented via an expired server-side session — fresh
64
+ // jar so only the (expired) cookie this seam returns is sent. The
65
+ // minted cookie payload is valid; the backdated `auth_session` row
66
+ // is what the DB-row expiry gate refuses.
67
+ const cookie = await fixture.mint_expired_session();
68
+ return { transport: fixture.fresh_transport(), headers: { cookie } };
69
+ }
70
+ case 'role_holder':
71
+ case 'wrong_role': {
72
+ const username = principals?.[as];
73
+ if (!username) {
74
+ throw new Error(`conformance: principal '${as}' requires options.principals.${as} naming a seeded ` +
75
+ `extra_accounts username (declare the account at setup via extra_accounts).`);
76
+ }
77
+ const extra = fixture.extra_accounts[username];
78
+ if (!extra) {
79
+ throw new Error(`conformance: extra_accounts['${username}'] not seeded for principal '${as}' — ` +
80
+ `declare it in the suite's extra_accounts option.`);
81
+ }
82
+ return { transport: fixture.fresh_transport(), headers: extra.create_session_headers() };
83
+ }
84
+ }
85
+ };
86
+ /** Assert each expected field deep-equals the corresponding response field. */
87
+ const assert_fields = (actual, fields, label) => {
88
+ assert.ok(actual !== null && typeof actual === 'object', `${label}: expected an object to read fields from, got ${JSON.stringify(actual)}`);
89
+ const record = actual;
90
+ for (const [key, expected] of Object.entries(fields)) {
91
+ assert.deepEqual(record[key], expected, `${label}: field '${key}'`);
92
+ }
93
+ };
94
+ const is_success_status = (status) => status >= 200 && status < 300;
95
+ /**
96
+ * Run one conformance case end-to-end: resolve the principal, dispatch the
97
+ * request, and assert the expected status / reason / fields.
98
+ */
99
+ const run_case = async (c, options, resolved_rpc_endpoints) => {
100
+ const fixture = await options.setup_test();
101
+ const { transport, headers, suppress_default_origin } = await resolve_principal(fixture, c.request.as, options.principals);
102
+ if (c.request.method.startsWith('/')) {
103
+ await run_rest_case(c, options, transport, headers);
104
+ return;
105
+ }
106
+ await run_rpc_case(c, transport, headers, suppress_default_origin, resolved_rpc_endpoints);
107
+ };
108
+ /** Dispatch + assert a case targeting an RPC method. */
109
+ const run_rpc_case = async (c, transport, headers, suppress_default_origin, resolved_rpc_endpoints) => {
110
+ const found = find_rpc_action(resolved_rpc_endpoints, c.request.method);
111
+ if (!found) {
112
+ throw new Error(`conformance: RPC method '${c.request.method}' not found on the surface — ` +
113
+ `check the method name or that the action is registered on rpc_endpoints.`);
114
+ }
115
+ const res = await rpc_call({
116
+ app: transport,
117
+ path: found.path,
118
+ method: c.request.method,
119
+ params: c.request.params,
120
+ headers,
121
+ ...(c.request.verb && { verb: c.request.verb }),
122
+ ...(suppress_default_origin && { suppress_default_origin: true }),
123
+ });
124
+ if (is_success_status(c.expect.status)) {
125
+ assert.ok(res.ok, `${c.name}: expected success (${c.expect.status}) but got error ${JSON.stringify(res.ok ? undefined : res.error)}`);
126
+ assert.strictEqual(res.status, c.expect.status, `${c.name}: status`);
127
+ const parsed = found.action.spec.output.safeParse(res.result);
128
+ assert.ok(parsed.success, `${c.name}: result does not match spec.output: ${JSON.stringify(parsed.success ? undefined : parsed.error.issues)}`);
129
+ if (c.expect.fields)
130
+ assert_fields(res.result, c.expect.fields, c.name);
131
+ return;
132
+ }
133
+ assert.ok(!res.ok, `${c.name}: expected error status ${c.expect.status} but got success`);
134
+ assert.strictEqual(res.status, c.expect.status, `${c.name}: error status`);
135
+ if (c.expect.error_reason !== undefined) {
136
+ const reason = res.error.data?.reason;
137
+ // Most RPC denials carry `error.data.reason` (incl. the pre-validation
138
+ // 401 now); a denial that genuinely omits it falls back to the status
139
+ // assertion above to pin the denial class.
140
+ if (reason !== undefined) {
141
+ assert.strictEqual(reason, c.expect.error_reason, `${c.name}: error.data.reason`);
142
+ }
143
+ }
144
+ if (c.expect.fields)
145
+ assert_fields(res.error.data, c.expect.fields, c.name);
146
+ };
147
+ /** Dispatch + assert a case targeting one of the 6 REST auth routes. */
148
+ const run_rest_case = async (c, options, transport, headers) => {
149
+ const suffix = c.request.method;
150
+ if (!rest_auth_route_suffixes.includes(suffix)) {
151
+ throw new Error(`conformance: REST method '${c.request.method}' is not a known auth-route suffix ` +
152
+ `(${rest_auth_route_suffixes.join(', ')}). Use an RPC method name for RPC actions.`);
153
+ }
154
+ const verb = c.request.verb ?? 'POST';
155
+ const route = find_auth_route(options.surface_source.route_specs, suffix, verb);
156
+ if (!route) {
157
+ throw new Error(`conformance: no REST route spec for ${verb} ${suffix} on the surface.`);
158
+ }
159
+ const init = {
160
+ method: verb,
161
+ headers: { 'Content-Type': 'application/json', ...headers },
162
+ ...(verb !== 'GET' &&
163
+ c.request.params !== undefined && { body: JSON.stringify(c.request.params) }),
164
+ };
165
+ const response = await transport(route.path, init);
166
+ assert.strictEqual(response.status, c.expect.status, `${c.name}: status`);
167
+ const body = await response.json().catch(() => undefined);
168
+ if (is_success_status(c.expect.status)) {
169
+ const parsed = route.output.safeParse(body);
170
+ assert.ok(parsed.success, `${c.name}: body does not match route output: ${JSON.stringify(parsed.success ? undefined : parsed.error.issues)}`);
171
+ }
172
+ else if (c.expect.error_reason !== undefined) {
173
+ const error = body?.error;
174
+ assert.strictEqual(error, c.expect.error_reason, `${c.name}: body.error`);
175
+ }
176
+ if (c.expect.fields)
177
+ assert_fields(body, c.expect.fields, c.name);
178
+ };
179
+ /**
180
+ * Register a `describe` block running every `ConformanceCase` as a
181
+ * vitest `test` (or `xfail_until` for deferred-by-design rows). Drives
182
+ * either transport via the shared `{setup_test, surface_source,
183
+ * capabilities}` protocol.
184
+ */
185
+ export const describe_conformance_table_tests = (options) => {
186
+ const resolved_rpc_endpoints = resolve_rpc_endpoints_for_setup(options.rpc_endpoints, options.session_options);
187
+ describe(options.suite_name ?? 'conformance table', () => {
188
+ for (const c of options.cases) {
189
+ const label = c.note ? `${c.name} — ${c.note}` : c.name;
190
+ const body = () => run_case(c, options, resolved_rpc_endpoints);
191
+ if (c.xfail) {
192
+ xfail_until(c.xfail.tracking_id, c.xfail.reason, label, body);
193
+ }
194
+ else {
195
+ test(label, body);
196
+ }
197
+ }
198
+ });
199
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"default_backend_configs.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/default_backend_configs.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAE9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,KAAK,EAAC,sBAAsB,EAAE,aAAa,EAAC,MAAM,qBAAqB,CAAC;AAC/E,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAA2B,KAAK,gBAAgB,EAAC,MAAM,+BAA+B,CAAC;AAQ9F;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,EAAE,mBAUpC,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,EAAE,mBAUtC,CAAC;AAeH,MAAM,WAAW,iCAAiC;IACjD,gFAAgF;IAChF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,sCAAsC;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,4DAA4D;IAC5D,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC9C,oDAAoD;IACpD,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,iEAAiE;IACjE,QAAQ,CAAC,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACtD,6CAA6C;IAC7C,QAAQ,CAAC,YAAY,CAAC,EAAE,mBAAmB,CAAC;IAC5C,wEAAwE;IACxE,QAAQ,CAAC,KAAK,CAAC,EAAE,gBAAgB,CAAC;IAClC,sEAAsE;IACtE,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC,sBAAsB,CAAC,CAAC;IAC/D;;;;OAIG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED;;;;;GAKG;AACH,eAAO,MAAM,8BAA8B,GAC1C,MAAM,iCAAiC,KACrC,aAmCF,CAAC;AAEF,MAAM,WAAW,mCAAmC;IACnD,gFAAgF;IAChF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,sCAAsC;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,4DAA4D;IAC5D,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC9C;;;;OAIG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,iEAAiE;IACjE,QAAQ,CAAC,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACtD,+CAA+C;IAC/C,QAAQ,CAAC,YAAY,CAAC,EAAE,mBAAmB,CAAC;IAC5C,wEAAwE;IACxE,QAAQ,CAAC,KAAK,CAAC,EAAE,gBAAgB,CAAC;IAClC,sEAAsE;IACtE,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC,sBAAsB,CAAC,CAAC;IAC/D;;;;OAIG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;GAKG;AACH,eAAO,MAAM,gCAAgC,GAC5C,MAAM,mCAAmC,KACvC,aA2CF,CAAC"}
1
+ {"version":3,"file":"default_backend_configs.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/default_backend_configs.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAE9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,KAAK,EAAC,sBAAsB,EAAE,aAAa,EAAC,MAAM,qBAAqB,CAAC;AAC/E,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAA2B,KAAK,gBAAgB,EAAC,MAAM,+BAA+B,CAAC;AAQ9F;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,EAAE,mBASpC,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,EAAE,mBAStC,CAAC;AAeH,MAAM,WAAW,iCAAiC;IACjD,gFAAgF;IAChF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,sCAAsC;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,4DAA4D;IAC5D,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC9C,oDAAoD;IACpD,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,iEAAiE;IACjE,QAAQ,CAAC,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACtD,6CAA6C;IAC7C,QAAQ,CAAC,YAAY,CAAC,EAAE,mBAAmB,CAAC;IAC5C,wEAAwE;IACxE,QAAQ,CAAC,KAAK,CAAC,EAAE,gBAAgB,CAAC;IAClC,sEAAsE;IACtE,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC,sBAAsB,CAAC,CAAC;IAC/D;;;;OAIG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED;;;;;GAKG;AACH,eAAO,MAAM,8BAA8B,GAC1C,MAAM,iCAAiC,KACrC,aAmCF,CAAC;AAEF,MAAM,WAAW,mCAAmC;IACnD,gFAAgF;IAChF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,sCAAsC;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,4DAA4D;IAC5D,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC9C;;;;OAIG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,iEAAiE;IACjE,QAAQ,CAAC,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACtD,+CAA+C;IAC/C,QAAQ,CAAC,YAAY,CAAC,EAAE,mBAAmB,CAAC;IAC5C,wEAAwE;IACxE,QAAQ,CAAC,KAAK,CAAC,EAAE,gBAAgB,CAAC;IAClC,sEAAsE;IACtE,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC,sBAAsB,CAAC,CAAC;IAC/D;;;;OAIG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;GAKG;AACH,eAAO,MAAM,gCAAgC,GAC5C,MAAM,mCAAmC,KACvC,aA2CF,CAAC"}
@@ -16,7 +16,6 @@ export const ts_default_capabilities = Object.freeze({
16
16
  cell_crud: true,
17
17
  cell_relations: true,
18
18
  account_lifecycle: true,
19
- in_process_only: false,
20
19
  });
21
20
  /**
22
21
  * Capabilities for the Rust family. Adds `trusted_proxy: true` (the
@@ -33,7 +32,6 @@ export const rust_default_capabilities = Object.freeze({
33
32
  cell_crud: true,
34
33
  cell_relations: true,
35
34
  account_lifecycle: true,
36
- in_process_only: false,
37
35
  });
38
36
  /** Bootstrap block built from the default secrets + supplied paths. */
39
37
  const build_default_bootstrap = (paths, overrides) => ({