@fuzdev/fuz_app 0.128.0 → 0.129.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 (87) hide show
  1. package/dist/actions/register_action_ws.d.ts +0 -1
  2. package/dist/actions/register_action_ws.d.ts.map +1 -1
  3. package/dist/auth/CLAUDE.md +1 -1
  4. package/dist/auth/actor_lookup_action_specs.d.ts +2 -2
  5. package/dist/auth/actor_lookup_action_specs.js +2 -2
  6. package/dist/auth/audit_emitter.d.ts +14 -7
  7. package/dist/auth/audit_emitter.d.ts.map +1 -1
  8. package/dist/auth/audit_emitter.js +6 -8
  9. package/dist/auth/bearer_auth.d.ts +3 -2
  10. package/dist/auth/bearer_auth.d.ts.map +1 -1
  11. package/dist/auth/bearer_auth.js +3 -2
  12. package/dist/auth/request_context.d.ts +1 -1
  13. package/dist/auth/request_context.js +1 -1
  14. package/dist/auth/token_scope.d.ts +4 -2
  15. package/dist/auth/token_scope.d.ts.map +1 -1
  16. package/dist/auth/token_scope.js +10 -2
  17. package/dist/http/CLAUDE.md +3 -4
  18. package/dist/http/auth_shape.d.ts +3 -2
  19. package/dist/http/auth_shape.d.ts.map +1 -1
  20. package/dist/http/auth_shape.js +3 -2
  21. package/dist/http/common_routes.d.ts +1 -14
  22. package/dist/http/common_routes.d.ts.map +1 -1
  23. package/dist/http/common_routes.js +1 -19
  24. package/dist/http/ip_canonical.d.ts +1 -1
  25. package/dist/http/ip_canonical.js +1 -1
  26. package/dist/realtime/sse_auth_guard.d.ts +3 -1
  27. package/dist/realtime/sse_auth_guard.d.ts.map +1 -1
  28. package/dist/realtime/sse_auth_guard.js +3 -1
  29. package/dist/server/app_server.d.ts +118 -7
  30. package/dist/server/app_server.d.ts.map +1 -1
  31. package/dist/server/app_server.js +136 -91
  32. package/dist/server/surface_route.d.ts +32 -0
  33. package/dist/server/surface_route.d.ts.map +1 -0
  34. package/dist/server/surface_route.js +46 -0
  35. package/dist/testing/CLAUDE.md +17 -12
  36. package/dist/testing/app_server.d.ts +39 -4
  37. package/dist/testing/app_server.d.ts.map +1 -1
  38. package/dist/testing/app_server.js +84 -68
  39. package/dist/testing/audit_completeness.js +1 -1
  40. package/dist/testing/audit_drift_guard.d.ts +1 -1
  41. package/dist/testing/cross_backend/default_spine_surface.d.ts +2 -2
  42. package/dist/testing/cross_backend/default_spine_surface.d.ts.map +1 -1
  43. package/dist/testing/cross_backend/default_spine_surface.js +5 -2
  44. package/dist/testing/cross_backend/identity_parity.js +1 -1
  45. package/dist/testing/cross_backend/in_process_setup.d.ts.map +1 -1
  46. package/dist/testing/cross_backend/in_process_setup.js +4 -1
  47. package/dist/testing/cross_backend/method_coverage.d.ts +1 -1
  48. package/dist/testing/cross_backend/method_coverage.d.ts.map +1 -1
  49. package/dist/testing/cross_backend/method_coverage.js +2 -2
  50. package/dist/testing/cross_backend/peer_ping_ws.d.ts +1 -1
  51. package/dist/testing/cross_backend/peer_ping_ws.d.ts.map +1 -1
  52. package/dist/testing/cross_backend/role_grant_offer_notification_ws.d.ts +1 -1
  53. package/dist/testing/cross_backend/role_grant_offer_notification_ws.d.ts.map +1 -1
  54. package/dist/testing/cross_backend/setup.d.ts +4 -4
  55. package/dist/testing/cross_backend/setup.js +1 -1
  56. package/dist/testing/cross_backend/sse_round_trip.d.ts +1 -1
  57. package/dist/testing/cross_backend/sse_round_trip.d.ts.map +1 -1
  58. package/dist/testing/cross_backend/testing_reset_actions.d.ts +24 -14
  59. package/dist/testing/cross_backend/testing_reset_actions.d.ts.map +1 -1
  60. package/dist/testing/cross_backend/testing_reset_actions.js +40 -32
  61. package/dist/testing/cross_backend/testing_server_bun.d.ts +1 -1
  62. package/dist/testing/cross_backend/testing_server_bun.d.ts.map +1 -1
  63. package/dist/testing/cross_backend/testing_server_bun.js +80 -64
  64. package/dist/testing/cross_backend/testing_server_core.d.ts +10 -4
  65. package/dist/testing/cross_backend/testing_server_core.d.ts.map +1 -1
  66. package/dist/testing/cross_backend/testing_server_deno.d.ts +1 -1
  67. package/dist/testing/cross_backend/testing_server_deno.d.ts.map +1 -1
  68. package/dist/testing/cross_backend/testing_server_deno.js +1 -1
  69. package/dist/testing/cross_backend/testing_server_node.d.ts +1 -1
  70. package/dist/testing/cross_backend/testing_server_node.d.ts.map +1 -1
  71. package/dist/testing/cross_backend/testing_server_node.js +2 -2
  72. package/dist/testing/cross_backend/ws_round_trip.d.ts +1 -1
  73. package/dist/testing/cross_backend/ws_round_trip.d.ts.map +1 -1
  74. package/dist/testing/cross_backend/ws_round_trip.js +11 -9
  75. package/dist/testing/stubs.d.ts +45 -7
  76. package/dist/testing/stubs.d.ts.map +1 -1
  77. package/dist/testing/stubs.js +60 -31
  78. package/dist/testing/ws_round_trip.d.ts +1 -3
  79. package/dist/testing/ws_round_trip.d.ts.map +1 -1
  80. package/dist/ui/AdminSurface.svelte +3 -1
  81. package/dist/ui/AdminSurface.svelte.d.ts.map +1 -1
  82. package/dist/ui/CLAUDE.md +3 -1
  83. package/dist/ui/async_slot.svelte.d.ts +4 -4
  84. package/dist/ui/async_slot.svelte.js +4 -4
  85. package/dist/ui/keyed_async_slot.svelte.d.ts +4 -4
  86. package/dist/ui/keyed_async_slot.svelte.js +3 -3
  87. package/package.json +1 -1
@@ -95,7 +95,6 @@ import type { Db } from '../db/db.js';
95
95
  import { type Action } from './action_types.js';
96
96
  import type { RealtimeCloser } from './connection_closer.js';
97
97
  import { BackendWebsocketTransport, type ConnectionIdentity } from './transports_ws_backend.js';
98
- export type { Action };
99
98
  /** Default inactivity window before the server closes a silent socket. */
100
99
  export declare const DEFAULT_SERVER_HEARTBEAT_TIMEOUT = 60000;
101
100
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"register_action_ws.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/register_action_ws.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"register_action_ws.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/register_action_ws.ts"],"names":[],"mappings":"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"}
@@ -124,7 +124,7 @@ upstream in `auth/signup_routes.ts` via `query_invite_find_unclaimed_match_for_u
124
124
  its registered listeners + optional `AuditLogConfig`. Its methods:
125
125
 
126
126
  - `emit(ctx, input)` — fire-and-forget pool write, pushes to `ctx.pending_effects`; a success row's listener fan-out goes on `ctx.post_commit_effects`
127
- - `emit_role_grant_target(ctx, auth, input)` — lifts `actor_id` / `account_id` / `ip` boilerplate for role-grant-shape events
127
+ - `emit_role_grant_target(ctx, auth, input)` — lifts `actor_id` / `account_id` / `ip` boilerplate for role-grant-shape events; `input` is an `AuditEmitRoleGrantInput`
128
128
  - `emit_pool(input)` — awaitable pool write for code paths without a request context (ad-hoc maintenance scripts; not for success audits paired with a mutation — those write in-tx and `notify` post-commit). Writes, then notifies, whatever the outcome
129
129
  - `notify(event)` — fan out an already-written row to listeners (used by in-tx audit batches like `query_accept_offer.audit_events`)
130
130
  - `add_listener(listener)` — listener registration, returning a remover for that registration (idempotent; the same function registered twice is two registrations, each with its own remover). Twin of Rust `fuz_auth` `AuditEmitter::add_listener` in firing order and snapshot-at-notify
@@ -12,7 +12,7 @@
12
12
  * Account-grain — only that the caller is signed in matters, not which
13
13
  * actor is calling, so resolution skips the actor phase. The auth gate
14
14
  * + per-account rate limit (default 1200/15min) + the
15
- * {@link ACTOR_LOOKUP_IDS_MAX | per-call cap} bound the batched
15
+ * per-call cap (`ACTOR_LOOKUP_IDS_MAX`) bound the batched
16
16
  * username-enumeration surface that the `cell_list` ↔ `actor_lookup`
17
17
  * pair would otherwise present.
18
18
  *
@@ -38,7 +38,7 @@
38
38
  * ids), bounded by:
39
39
  *
40
40
  * 1. rate-limit (per-account, see above),
41
- * 2. {@link ACTOR_LOOKUP_IDS_MAX} cap per call,
41
+ * 2. `ACTOR_LOOKUP_IDS_MAX` cap per call,
42
42
  * 3. actor-uuid intractability (122-bit random),
43
43
  * 4. hard-deleted actors are indistinguishable from never-existed (no
44
44
  * tombstone oracle — see `auth/actor_lookup_queries.ts`).
@@ -12,7 +12,7 @@
12
12
  * Account-grain — only that the caller is signed in matters, not which
13
13
  * actor is calling, so resolution skips the actor phase. The auth gate
14
14
  * + per-account rate limit (default 1200/15min) + the
15
- * {@link ACTOR_LOOKUP_IDS_MAX | per-call cap} bound the batched
15
+ * per-call cap (`ACTOR_LOOKUP_IDS_MAX`) bound the batched
16
16
  * username-enumeration surface that the `cell_list` ↔ `actor_lookup`
17
17
  * pair would otherwise present.
18
18
  *
@@ -38,7 +38,7 @@
38
38
  * ids), bounded by:
39
39
  *
40
40
  * 1. rate-limit (per-account, see above),
41
- * 2. {@link ACTOR_LOOKUP_IDS_MAX} cap per call,
41
+ * 2. `ACTOR_LOOKUP_IDS_MAX` cap per call,
42
42
  * 3. actor-uuid intractability (122-bit random),
43
43
  * 4. hard-deleted actors are indistinguishable from never-existed (no
44
44
  * tombstone oracle — see `auth/actor_lookup_queries.ts`).
@@ -102,6 +102,19 @@ export interface AuditEmitRoleGrantContext extends AuditEmitterContext {
102
102
  /** Resolved client IP from the trusted-proxy middleware — `'unknown'` if not resolved. */
103
103
  client_ip: string;
104
104
  }
105
+ /**
106
+ * Input to `AuditEmitter.emit_role_grant_target` — the event fields that
107
+ * vary per call site; `actor_id`, `account_id`, and `ip` are lifted from
108
+ * the auth and request contexts.
109
+ */
110
+ export interface AuditEmitRoleGrantInput<T extends string> {
111
+ event_type: T;
112
+ target_account_id: Uuid | null;
113
+ target_actor_id: Uuid | null;
114
+ metadata: AuditLogInput<T>['metadata'];
115
+ /** Default `'success'`, as for `emit`. */
116
+ outcome?: 'success' | 'failure';
117
+ }
105
118
  /**
106
119
  * Bound audit-emit capability. Built once at backend assembly via
107
120
  * `create_audit_emitter`; lives on `AppDeps.audit` so factories never see
@@ -137,13 +150,7 @@ export interface AuditEmitter {
137
150
  * Reach for the lower-level `emit` only when the event is non-role-grant
138
151
  * shape (e.g. `app_settings_update`, bootstrap, signup).
139
152
  */
140
- emit_role_grant_target<T extends string>(ctx: AuditEmitRoleGrantContext, auth: RequestActorContext, input: {
141
- event_type: T;
142
- target_account_id: Uuid | null;
143
- target_actor_id: Uuid | null;
144
- metadata: AuditLogInput<T>['metadata'];
145
- outcome?: 'success' | 'failure';
146
- }): void;
153
+ emit_role_grant_target<T extends string>(ctx: AuditEmitRoleGrantContext, auth: RequestActorContext, input: AuditEmitRoleGrantInput<T>): void;
147
154
  /**
148
155
  * Awaitable pool write for code paths without a request context.
149
156
  *
@@ -1 +1 @@
1
- {"version":3,"file":"audit_emitter.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/audit_emitter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"audit_emitter.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/audit_emitter.ts"],"names":[],"mappings":"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"}
@@ -187,16 +187,14 @@ export const create_audit_emitter = (options) => {
187
187
  };
188
188
  const listener_count = () => listeners.length;
189
189
  // Freeze the slot layout so consumers cannot hot-patch `emit` /
190
- // `emit_role_grant_target` / `emit_pool` / `notify` after construction.
191
- // The previous test helper `patch_audit_emit_capture` did exactly this
192
- // and only happened to work because the four slots were writable —
190
+ // `emit_role_grant_target` / `emit_pool` / `notify` after construction —
191
+ // a patched `emit` would miss role-grant-shape emits anyway, since
193
192
  // `emit_role_grant_target` calls the closed-over inner `emit`, not
194
- // `this.emit`, so the patch silently bypassed role-grant-shape emits.
195
- // Tests that need instrumentation pass `emit_decorator` so the wrap
196
- // is captured by the closure before the freeze. The listener list stays
193
+ // `this.emit`. Tests that need instrumentation pass `emit_decorator` so the
194
+ // wrap is captured by the closure before the freeze. The listener list stays
197
195
  // closure-private; it changes only through `add_listener` and the remover
198
- // it returns (`create_app_server` registers its SSE + WS listeners
199
- // post-assembly, by design, and removes them on close).
196
+ // it returns (`create_app_server` registers its SSE + WS listeners after
197
+ // the emitter is built, by design, and removes them on close).
200
198
  return Object.freeze({
201
199
  emit,
202
200
  emit_role_grant_target,
@@ -28,8 +28,9 @@ import type { QueryDeps } from '../db/query_deps.js';
28
28
  * (`invalid_token`, `account_not_found`) that could aid enumeration attacks,
29
29
  * and ensures public actions are not blocked by bad credentials.
30
30
  *
31
- * Rejects bearer tokens when an `Origin` or `Referer` header is present —
32
- * browsers must use cookie auth to reduce attack surface.
31
+ * Discards bearer tokens when an `Origin` or `Referer` header is present —
32
+ * `next()` with no identity, as for a bad token — so browsers must use cookie
33
+ * auth, reducing attack surface.
33
34
  * Auth scheme matching is case-insensitive per RFC 7235.
34
35
  * On success, sets `c.var.auth_account_id`, `CREDENTIAL_TYPE_KEY = 'api_token'`,
35
36
  * and `AUTH_API_TOKEN_ID_KEY`. Skips when an account is already authenticated
@@ -1 +1 @@
1
- {"version":3,"file":"bearer_auth.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/bearer_auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAC9C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAUtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAIrD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,eAAO,MAAM,6BAA6B,GAAI,MAAM,SAAS,EAAE,KAAK,MAAM,KAAG,iBAuE5E,CAAC"}
1
+ {"version":3,"file":"bearer_auth.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/bearer_auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAC9C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAUtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAIrD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,eAAO,MAAM,6BAA6B,GAAI,MAAM,SAAS,EAAE,KAAK,MAAM,KAAG,iBAuE5E,CAAC"}
@@ -31,8 +31,9 @@ import { is_browser_context } from '../http/origin.js';
31
31
  * (`invalid_token`, `account_not_found`) that could aid enumeration attacks,
32
32
  * and ensures public actions are not blocked by bad credentials.
33
33
  *
34
- * Rejects bearer tokens when an `Origin` or `Referer` header is present —
35
- * browsers must use cookie auth to reduce attack surface.
34
+ * Discards bearer tokens when an `Origin` or `Referer` header is present —
35
+ * `next()` with no identity, as for a bad token — so browsers must use cookie
36
+ * auth, reducing attack surface.
36
37
  * Auth scheme matching is case-insensitive per RFC 7235.
37
38
  * On success, sets `c.var.auth_account_id`, `CREDENTIAL_TYPE_KEY = 'api_token'`,
38
39
  * and `AUTH_API_TOKEN_ID_KEY`. Skips when an account is already authenticated
@@ -251,7 +251,7 @@ export declare const create_request_context_middleware: (deps: QueryDeps, sessio
251
251
  * across route-spec declarations and direct calls alike, and the twin of the
252
252
  * Rust signature. It needs no parse: the surface arm's identifier is pure label,
253
253
  * since rule 3 never asks *which* surface. And it is deliberately not narrowed
254
- * to the spine's four — the name decides nothing, so there is nothing for a
254
+ * to the spine's own — the name decides nothing, so there is nothing for a
255
255
  * closed set to protect, while a consumer surface would have nothing to pass.
256
256
  * fuz_app's own uses are pinned two ways by the surface census: the exact call
257
257
  * site, and the scan asserting every `'surface:<name>'` literal in `src/lib`
@@ -281,7 +281,7 @@ const token_scope_denial = (c, capability) => {
281
281
  * across route-spec declarations and direct calls alike, and the twin of the
282
282
  * Rust signature. It needs no parse: the surface arm's identifier is pure label,
283
283
  * since rule 3 never asks *which* surface. And it is deliberately not narrowed
284
- * to the spine's four — the name decides nothing, so there is nothing for a
284
+ * to the spine's own — the name decides nothing, so there is nothing for a
285
285
  * closed set to protect, while a consumer surface would have nothing to pass.
286
286
  * fuz_app's own uses are pinned two ways by the surface census: the exact call
287
287
  * site, and the scan asserting every `'surface:<name>'` literal in `src/lib`
@@ -106,7 +106,9 @@ export declare const token_scope_admits_method: (scope: TokenScope, method: stri
106
106
  export declare const token_scope_admits_non_rpc: (scope: TokenScope) => boolean;
107
107
  /**
108
108
  * The non-RPC surfaces the **spine itself** mounts (rule 3). Twin of the Rust
109
- * `TokenSurface` enum, name for name.
109
+ * `TokenSurface` enum, name for name, except `app_surface` — the opt-in
110
+ * `GET /api/surface` explorer (`server/surface_route.ts`), which only the TS
111
+ * spine serves.
110
112
  *
111
113
  * Not a registry a consumer registers into. `RouteAuth.required_scope` accepts
112
114
  * any well-formed `surface:<name>` (see `parse_token_scope_capability`), so a
@@ -120,7 +122,7 @@ export declare const token_scope_admits_non_rpc: (scope: TokenScope) => boolean;
120
122
  * refused, in the `required_scope` a denial reports. That is the same field
121
123
  * whose `rpc:<method>` arm has always carried arbitrary consumer method names.
122
124
  */
123
- export declare const TOKEN_SURFACES: readonly ["db_admin", "fact_bare", "audit_stream", "ws_upgrade"];
125
+ export declare const TOKEN_SURFACES: readonly ["db_admin", "fact_bare", "audit_stream", "ws_upgrade", "app_surface"];
124
126
  export type TokenSurface = (typeof TOKEN_SURFACES)[number];
125
127
  /**
126
128
  * Is `value` one of the surfaces the spine mounts?
@@ -1 +1 @@
1
- {"version":3,"file":"token_scope.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/token_scope.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,wFAAwF;AACxF,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAErC;;;GAGG;AACH,eAAO,MAAM,qBAAqB,QAAW,CAAC;AAE9C;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,UAAU;;;;;;;;;4BAYrB,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAEpD;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe;;;;;4BAG1B,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAE9D,kDAAkD;AAClD,eAAO,MAAM,gBAAgB,QAAO,UAGlC,CAAC;AAEH,uCAAuC;AACvC,eAAO,MAAM,mBAAmB,GAAI,SAAS,KAAK,CAAC,MAAM,CAAC,KAAG,UAI3D,CAAC;AAEH,qDAAqD;AACrD,eAAO,MAAM,sBAAsB,GAAI,OAAO,eAAe,KAAG,UACgB,CAAC;AAEjF;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,GAAI,OAAO,UAAU,EAAE,QAAQ,MAAM,KAAG,OACtB,CAAC;AAEzD;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,0BAA0B,GAAI,OAAO,UAAU,KAAG,OAAgC,CAAC;AAEhG;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,cAAc,kEAAmE,CAAC;AAC/F,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAE3D;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB,GAAI,OAAO,MAAM,KAAG,KAAK,IAAI,YACA,CAAC;AAE3D;;;;;;;;GAQG;AACH,eAAO,MAAM,wBAAwB,QAAgC,CAAC;AAQtE;;;;;;GAMG;AACH,eAAO,MAAM,6BAA6B,GAAI,QAAQ,MAAM,KAAG,MAC3B,CAAC;AAErC;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,oBAAoB,GAC/B;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/F;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,4BAA4B,GAAI,OAAO,MAAM,KAAG,oBAAoB,GAAG,IAUnF,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,6BAA6B,GACzC,OAAO,UAAU,EACjB,YAAY,oBAAoB,KAC9B,OAGkC,CAAC;AAEtC;;;;;;;;;GASG;AACH,eAAO,MAAM,uBAAuB,GACnC,YAAY,MAAM,KAChB;IAAE,KAAK,EAAE,sBAAsB,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAGxD,CAAC;AAEH,4CAA4C;AAC5C,eAAO,MAAM,iBAAiB,GAAI,OAAO,UAAU,KAAG,MAGrD,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,GAAI,KAAK,MAAM,KAAG,UAAU,GAAG,IAU5D,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,GAAI,OAAO,UAAU,KAAG,MAQzD,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,wBAAwB,GAAI,OAAO,OAAO,KAAG,UAAU,GAAG,IAQtE,CAAC"}
1
+ {"version":3,"file":"token_scope.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/auth/token_scope.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,wFAAwF;AACxF,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAErC;;;GAGG;AACH,eAAO,MAAM,qBAAqB,QAAW,CAAC;AAE9C;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,UAAU;;;;;;;;;4BAYrB,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAEpD;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe;;;;;4BAG1B,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAE9D,kDAAkD;AAClD,eAAO,MAAM,gBAAgB,QAAO,UAGlC,CAAC;AAEH,uCAAuC;AACvC,eAAO,MAAM,mBAAmB,GAAI,SAAS,KAAK,CAAC,MAAM,CAAC,KAAG,UAI3D,CAAC;AAEH,qDAAqD;AACrD,eAAO,MAAM,sBAAsB,GAAI,OAAO,eAAe,KAAG,UACgB,CAAC;AAEjF;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,GAAI,OAAO,UAAU,EAAE,QAAQ,MAAM,KAAG,OACtB,CAAC;AAEzD;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,0BAA0B,GAAI,OAAO,UAAU,KAAG,OAAgC,CAAC;AAEhG;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,cAAc,iFAMjB,CAAC;AACX,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAE3D;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB,GAAI,OAAO,MAAM,KAAG,KAAK,IAAI,YACA,CAAC;AAE3D;;;;;;;;GAQG;AACH,eAAO,MAAM,wBAAwB,QAAgC,CAAC;AAQtE;;;;;;GAMG;AACH,eAAO,MAAM,6BAA6B,GAAI,QAAQ,MAAM,KAAG,MAC3B,CAAC;AAErC;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,oBAAoB,GAC/B;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/F;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,4BAA4B,GAAI,OAAO,MAAM,KAAG,oBAAoB,GAAG,IAUnF,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,6BAA6B,GACzC,OAAO,UAAU,EACjB,YAAY,oBAAoB,KAC9B,OAGkC,CAAC;AAEtC;;;;;;;;;GASG;AACH,eAAO,MAAM,uBAAuB,GACnC,YAAY,MAAM,KAChB;IAAE,KAAK,EAAE,sBAAsB,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAGxD,CAAC;AAEH,4CAA4C;AAC5C,eAAO,MAAM,iBAAiB,GAAI,OAAO,UAAU,KAAG,MAGrD,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,GAAI,KAAK,MAAM,KAAG,UAAU,GAAG,IAU5D,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,GAAI,OAAO,UAAU,KAAG,MAQzD,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,wBAAwB,GAAI,OAAO,OAAO,KAAG,UAAU,GAAG,IAQtE,CAAC"}
@@ -112,7 +112,9 @@ export const token_scope_admits_method = (scope, method) => scope.kind === 'full
112
112
  export const token_scope_admits_non_rpc = (scope) => scope.kind === 'full';
113
113
  /**
114
114
  * The non-RPC surfaces the **spine itself** mounts (rule 3). Twin of the Rust
115
- * `TokenSurface` enum, name for name.
115
+ * `TokenSurface` enum, name for name, except `app_surface` — the opt-in
116
+ * `GET /api/surface` explorer (`server/surface_route.ts`), which only the TS
117
+ * spine serves.
116
118
  *
117
119
  * Not a registry a consumer registers into. `RouteAuth.required_scope` accepts
118
120
  * any well-formed `surface:<name>` (see `parse_token_scope_capability`), so a
@@ -126,7 +128,13 @@ export const token_scope_admits_non_rpc = (scope) => scope.kind === 'full';
126
128
  * refused, in the `required_scope` a denial reports. That is the same field
127
129
  * whose `rpc:<method>` arm has always carried arbitrary consumer method names.
128
130
  */
129
- export const TOKEN_SURFACES = ['db_admin', 'fact_bare', 'audit_stream', 'ws_upgrade'];
131
+ export const TOKEN_SURFACES = [
132
+ 'db_admin',
133
+ 'fact_bare',
134
+ 'audit_stream',
135
+ 'ws_upgrade',
136
+ 'app_surface'
137
+ ];
130
138
  /**
131
139
  * Is `value` one of the surfaces the spine mounts?
132
140
  *
@@ -28,7 +28,7 @@ effects, see ../../../docs/architecture.md.
28
28
  - `http/jsonrpc.ts` — JSON-RPC 2.0 envelope schemas (MCP superset), `JsonrpcErrorCode`, `_meta`.
29
29
  - `http/jsonrpc_errors.ts` — `ThrownJsonrpcError`, `jsonrpc_errors` throwers, HTTP-status mappings.
30
30
  - `http/jsonrpc_helpers.ts` — message builders, type guards, input/result normalizers.
31
- - `http/common_routes.ts` — health check + readiness probe (`/ready` schema-drift deploy gate) + authenticated server-status + surface route specs.
31
+ - `http/common_routes.ts` — health check + readiness probe (`/ready` schema-drift deploy gate) + authenticated server-status route specs (the surface explorer route lives in `server/surface_route.ts`).
32
32
  - `http/db_routes.ts` — allowlist-gated keeper-only table browser route specs (`public` schema, minus the `NON_BROWSABLE_TABLES` credential floor).
33
33
  - `http/pending_effects.ts` — `emit_after_commit` + `dispatch_with_post_commit_rollback` (the shared rollback-discard wrapper both dispatch sites use) + `flush_pending_effects` + `flush_post_commit_effects` + `EmitAfterCommitContext`.
34
34
 
@@ -484,13 +484,12 @@ at send time.
484
484
 
485
485
  ## Common Routes
486
486
 
487
- `http/common_routes.ts` exposes four generic route-spec factories with no
487
+ `http/common_routes.ts` exposes three generic route-spec factories with no
488
488
  auth-domain dependencies:
489
489
 
490
490
  - `create_health_route_spec()` — `GET /health`, public, returns `{status: 'ok'}`. Infrastructure endpoint for uptime monitors
491
- - `create_ready_route_spec({expected, log})` — `GET /ready`, public, the deploy gate. Introspects the live DB's columns (`db/schema_ready.ts`) and compares against the committed `expected` column map: `200 {ready: true}` on match, else `503 {error: 'schema_drift' | 'db_unreachable'}`. Detailed drift logs server-side only (minimal body — no schema leak, mirrors why `/api/surface` is authenticated). Throws at assembly on an empty `expected` (fail-loud). Opt-in like `/health`; pair with `load_expected_schema(url)` — loads + URL-caches a consumer's committed `expected_schema.json` and throws on an empty map
491
+ - `create_ready_route_spec({expected, log})` — `GET /ready`, public, the deploy gate. Introspects the live DB's columns (`db/schema_ready.ts`) and compares against the committed `expected` column map: `200 {ready: true}` on match, else `503 {error: 'schema_drift' | 'db_unreachable'}`. Detailed drift logs server-side only (minimal body — no schema leak, mirrors why `/api/surface` is admin-only). Throws at assembly on an empty `expected` (fail-loud). Opt-in like `/health`; pair with `load_expected_schema(url)` — loads + URL-caches a consumer's committed `expected_schema.json` and throws on an empty map
492
492
  - `create_server_status_route_spec({version, get_uptime_ms})` — `GET /api/server/status`, authenticated, returns `{version, uptime_ms}`
493
- - `create_surface_route_spec({surface})` — `GET /api/surface`, authenticated, serves the `AppSurface` JSON. Authenticated because surface data reveals API structure (schemas, auth, routes)
494
493
 
495
494
  Auth-aware variants (account status, bootstrap status) live in `auth/` —
496
495
  `http/common_routes.ts` stays generic.
@@ -141,8 +141,9 @@ export declare const RouteAuth: z.ZodObject<{
141
141
  *
142
142
  * - `surface:<name>` — a non-RPC surface, refused to every narrowed token
143
143
  * whatever its method list says (token scoping's rule that a narrowed
144
- * token is RPC-only). `surface:audit_stream` and `surface:fact_bare` are
145
- * the spine's; a consumer names its own without registering it.
144
+ * token is RPC-only). `surface:audit_stream`, `surface:fact_bare`, and
145
+ * `surface:app_surface` are the spine's route-spec ones; a consumer names
146
+ * its own without registering it.
146
147
  * - `rpc:<method>` — one action method, refused unless the token lists it.
147
148
  * What a route bridged from an `ActionSpec` declares: it carries the
148
149
  * method's identity but never reaches the dispatcher's per-method gate.
@@ -1 +1 @@
1
- {"version":3,"file":"auth_shape.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/http/auth_shape.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,WAAW,6DAGtB,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAEtD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,YAAY,GAAI,OAAO,OAAO,KAAG,MAAM,GAAG,SAGtD,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,aAAa;;;;EAA2C,CAAC;AACtE,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,SAAS;;;;;;;;;;;;;IAMpB;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;;kBAyCF,CAAC;AACJ,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAC;AAUlD;;;;;GAKG;AACH,eAAO,MAAM,cAAc,GAAI,MAAM,SAAS,KAAG,OACA,CAAC;AAElD;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,GAAI,MAAM,SAAS,KAAG,OAAgC,CAAC;AAE/E;;;;GAIG;AACH,eAAO,MAAM,aAAa,GAAI,MAAM,SAAS,KAAG,OAAkC,CAAC;AAEnF,wEAAwE;AACxE,eAAO,MAAM,YAAY,GAAI,MAAM,SAAS,KAAG,OAA+B,CAAC;AAE/E,8FAA8F;AAC9F,eAAO,MAAM,wBAAwB,GAAI,MAAM,SAAS,KAAG,OAC3B,CAAC;AAEjC;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,cAAc,GAAI,MAAM,SAAS,KAAG,OACQ,CAAC;AAE1D;;;;;;;;;;GAUG;AACH,eAAO,MAAM,2BAA2B,GAAI,MAAM,SAAS,KAAG,OACwB,CAAC;AAYvF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,4BAA4B,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,OAIhE,CAAC;AAEF;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC3B,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,sCAAsC,GAClD,MAAM,SAAS,EACf,OAAO,WAAW,EAClB,SAAS,MAAM,KACb,IAmBF,CAAC"}
1
+ {"version":3,"file":"auth_shape.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/http/auth_shape.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,WAAW,6DAGtB,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAEtD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,YAAY,GAAI,OAAO,OAAO,KAAG,MAAM,GAAG,SAGtD,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,aAAa;;;;EAA2C,CAAC;AACtE,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,SAAS;;;;;;;;;;;;;IAMpB;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;;kBAyCF,CAAC;AACJ,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAC;AAUlD;;;;;GAKG;AACH,eAAO,MAAM,cAAc,GAAI,MAAM,SAAS,KAAG,OACA,CAAC;AAElD;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,GAAI,MAAM,SAAS,KAAG,OAAgC,CAAC;AAE/E;;;;GAIG;AACH,eAAO,MAAM,aAAa,GAAI,MAAM,SAAS,KAAG,OAAkC,CAAC;AAEnF,wEAAwE;AACxE,eAAO,MAAM,YAAY,GAAI,MAAM,SAAS,KAAG,OAA+B,CAAC;AAE/E,8FAA8F;AAC9F,eAAO,MAAM,wBAAwB,GAAI,MAAM,SAAS,KAAG,OAC3B,CAAC;AAEjC;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,cAAc,GAAI,MAAM,SAAS,KAAG,OACQ,CAAC;AAE1D;;;;;;;;;;GAUG;AACH,eAAO,MAAM,2BAA2B,GAAI,MAAM,SAAS,KAAG,OACwB,CAAC;AAYvF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,4BAA4B,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,OAIhE,CAAC;AAEF;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC3B,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,sCAAsC,GAClD,MAAM,SAAS,EACf,OAAO,WAAW,EAClB,SAAS,MAAM,KACb,IAmBF,CAAC"}
@@ -135,8 +135,9 @@ export const RouteAuth = z
135
135
  *
136
136
  * - `surface:<name>` — a non-RPC surface, refused to every narrowed token
137
137
  * whatever its method list says (token scoping's rule that a narrowed
138
- * token is RPC-only). `surface:audit_stream` and `surface:fact_bare` are
139
- * the spine's; a consumer names its own without registering it.
138
+ * token is RPC-only). `surface:audit_stream`, `surface:fact_bare`, and
139
+ * `surface:app_surface` are the spine's route-spec ones; a consumer names
140
+ * its own without registering it.
140
141
  * - `rpc:<method>` — one action method, refused unless the token lists it.
141
142
  * What a route bridged from an `ActionSpec` declares: it carries the
142
143
  * method's identity but never reaches the dispatcher's per-method gate.
@@ -8,7 +8,6 @@
8
8
  */
9
9
  import type { Logger } from '@fuzdev/fuz_util/log.ts';
10
10
  import type { RouteSpec } from './route_spec.js';
11
- import type { AppSurface } from './surface.js';
12
11
  import { type ExpectedSchema } from '../db/schema_ready.js';
13
12
  /**
14
13
  * Create a public health check route spec.
@@ -57,7 +56,7 @@ export interface ReadyRouteOptions {
57
56
  * else `503 {error}` (`schema_drift` when columns are missing, `db_unreachable`
58
57
  * when the introspection query throws). The detailed drift goes to the server
59
58
  * log only — the public body stays a minimal code so the endpoint doesn't leak
60
- * schema structure (mirrors why `/api/surface` is authenticated). A deploy poll
59
+ * schema structure (mirrors why `/api/surface` is admin-only). A deploy poll
61
60
  * treats `503` as a failed release and rolls back, turning a silent
62
61
  * schema-drift auth outage into a loud blocked deploy. See `db/schema_ready.ts`
63
62
  * for the column-presence rationale and `auth/migrations.ts` for the
@@ -78,16 +77,4 @@ export interface ServerStatusOptions {
78
77
  * this requires authentication.
79
78
  */
80
79
  export declare const create_server_status_route_spec: (options: ServerStatusOptions) => RouteSpec;
81
- /** Options for the surface explorer route. */
82
- export interface SurfaceRouteOptions {
83
- /** The generated app surface to serve. */
84
- surface: AppSurface;
85
- }
86
- /**
87
- * Create an authenticated route spec that serves the `AppSurface` as JSON.
88
- *
89
- * Surface data reveals API structure (routes, auth, schemas), so this
90
- * requires authentication like the server status route.
91
- */
92
- export declare const create_surface_route_spec: (options: SurfaceRouteOptions) => RouteSpec;
93
80
  //# sourceMappingURL=common_routes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"common_routes.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/http/common_routes.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAEtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAIN,KAAK,cAAc,EACnB,MAAM,uBAAuB,CAAC;AAE/B;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,QAAO,SAQ1C,CAAC;AAKH;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,oBAAoB,GAAI,KAAK,GAAG,GAAG,MAAM,KAAG,cAkBxD,CAAC;AAEF,6CAA6C;AAC7C,MAAM,WAAW,iBAAiB;IACjC;;;;OAIG;IACH,QAAQ,EAAE,cAAc,CAAC;IACzB,gFAAgF;IAChF,GAAG,CAAC,EAAE,MAAM,CAAC;CACb;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,uBAAuB,GAAI,SAAS,iBAAiB,KAAG,SAoCpE,CAAC;AAEF,yDAAyD;AACzD,MAAM,WAAW,mBAAmB;IACnC,kCAAkC;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,+CAA+C;IAC/C,aAAa,EAAE,MAAM,MAAM,CAAC;CAC5B;AAED;;;;;GAKG;AACH,eAAO,MAAM,+BAA+B,GAAI,SAAS,mBAAmB,KAAG,SAQ7E,CAAC;AAEH,8CAA8C;AAC9C,MAAM,WAAW,mBAAmB;IACnC,0CAA0C;IAC1C,OAAO,EAAE,UAAU,CAAC;CACpB;AAED;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,GAAI,SAAS,mBAAmB,KAAG,SAWvE,CAAC"}
1
+ {"version":3,"file":"common_routes.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/http/common_routes.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAEtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAIN,KAAK,cAAc,EACnB,MAAM,uBAAuB,CAAC;AAE/B;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,QAAO,SAQ1C,CAAC;AAKH;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,oBAAoB,GAAI,KAAK,GAAG,GAAG,MAAM,KAAG,cAkBxD,CAAC;AAEF,6CAA6C;AAC7C,MAAM,WAAW,iBAAiB;IACjC;;;;OAIG;IACH,QAAQ,EAAE,cAAc,CAAC;IACzB,gFAAgF;IAChF,GAAG,CAAC,EAAE,MAAM,CAAC;CACb;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,uBAAuB,GAAI,SAAS,iBAAiB,KAAG,SAoCpE,CAAC;AAEF,yDAAyD;AACzD,MAAM,WAAW,mBAAmB;IACnC,kCAAkC;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,+CAA+C;IAC/C,aAAa,EAAE,MAAM,MAAM,CAAC;CAC5B;AAED;;;;;GAKG;AACH,eAAO,MAAM,+BAA+B,GAAI,SAAS,mBAAmB,KAAG,SAQ7E,CAAC"}
@@ -71,7 +71,7 @@ export const load_expected_schema = (url) => {
71
71
  * else `503 {error}` (`schema_drift` when columns are missing, `db_unreachable`
72
72
  * when the introspection query throws). The detailed drift goes to the server
73
73
  * log only — the public body stays a minimal code so the endpoint doesn't leak
74
- * schema structure (mirrors why `/api/surface` is authenticated). A deploy poll
74
+ * schema structure (mirrors why `/api/surface` is admin-only). A deploy poll
75
75
  * treats `503` as a failed release and rolls back, turning a silent
76
76
  * schema-drift auth outage into a loud blocked deploy. See `db/schema_ready.ts`
77
77
  * for the column-presence rationale and `auth/migrations.ts` for the
@@ -129,21 +129,3 @@ export const create_server_status_route_spec = (options) => ({
129
129
  input: z.null(),
130
130
  output: z.looseObject({ version: z.string(), uptime_ms: z.number() })
131
131
  });
132
- /**
133
- * Create an authenticated route spec that serves the `AppSurface` as JSON.
134
- *
135
- * Surface data reveals API structure (routes, auth, schemas), so this
136
- * requires authentication like the server status route.
137
- */
138
- export const create_surface_route_spec = (options) => ({
139
- method: 'GET',
140
- path: '/api/surface',
141
- auth: { account: 'required', actor: 'none' },
142
- handler: (c) => c.json(options.surface),
143
- description: 'Application surface (routes, middleware, schemas)',
144
- input: z.null(),
145
- output: z.looseObject({
146
- routes: z.array(z.looseObject({})),
147
- middleware: z.array(z.looseObject({}))
148
- })
149
- });
@@ -12,7 +12,7 @@
12
12
  * IPv6 forms (`::ffff:127.0.0.1` vs `0:0:0:0:0:ffff:7f00:1` vs the
13
13
  * bare `127.0.0.1`) — three keys for one address.
14
14
  *
15
- * Canonicalization runs through {@link canonicalize_ip} which:
15
+ * Canonicalization runs through `canonicalize_ip` which:
16
16
  *
17
17
  * 1. Lowercases and char-set filters (`IP_LITERAL_CHARS`) — non-IP
18
18
  * strings (`'unknown'`, `'attacker:controlled'`, `'::1\n'`) pass
@@ -12,7 +12,7 @@
12
12
  * IPv6 forms (`::ffff:127.0.0.1` vs `0:0:0:0:0:ffff:7f00:1` vs the
13
13
  * bare `127.0.0.1`) — three keys for one address.
14
14
  *
15
- * Canonicalization runs through {@link canonicalize_ip} which:
15
+ * Canonicalization runs through `canonicalize_ip` which:
16
16
  *
17
17
  * 1. Lowercases and char-set filters (`IP_LITERAL_CHARS`) — non-IP
18
18
  * strings (`'unknown'`, `'attacker:controlled'`, `'::1\n'`) pass
@@ -118,7 +118,9 @@ export declare const AUDIT_LOG_SSE_MAX_PER_SCOPE = 10;
118
118
  * connection closer.
119
119
  *
120
120
  * Combines `SubscriberRegistry`, `create_sse_auth_guard`, and the broadcast
121
- * call into a single object, and adds the registry to `connection_closer`.
121
+ * call into a single object, and adds the registry to `connection_closer` for
122
+ * good — the remover `add` returns is dropped, so a caller that must take the
123
+ * registry out again passes `null` and adds it itself.
122
124
  * The result satisfies `AuditLogRouteOptions['stream']`
123
125
  * and provides the `on_audit_event` listener for the audit emitter.
124
126
  *
@@ -1 +1 @@
1
- {"version":3,"file":"sse_auth_guard.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/realtime/sse_auth_guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAGtD,OAAO,EAIN,KAAK,aAAa,EAClB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACxF,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAE3D,2DAA2D;AAC3D,eAAO,MAAM,iBAAiB,cAAc,CAAC;AAE7C;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,4BAA4B,GAAI,CAAC,EAC7C,UAAU,kBAAkB,CAAC,CAAC,CAAC,KAC7B,gBAKD,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,eAAO,MAAM,qBAAqB,GAAI,CAAC,EACtC,UAAU,kBAAkB,CAAC,CAAC,CAAC,EAC/B,eAAe,MAAM,GAAG,IAAI,EAC5B,KAAK,MAAM,KACT,CAAC,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CA4DjC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC3B;;;;;OAKG;IACH,QAAQ,EAAE,kBAAkB,CAAC,eAAe,CAAC,CAAC;IAC9C,kFAAkF;IAClF,GAAG,EAAE,MAAM,CAAC;IACZ,yJAAyJ;IACzJ,cAAc,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;CAC/C;AAED;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,EAAE,KAAK,CAAC,SAAS,CAOlD,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,2BAA2B,KAAK,CAAC;AAE9C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,eAAO,MAAM,oBAAoB,GAAI,SAAS;IAC7C,mEAAmE;IACnE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;;;;;OASG;IACH,iBAAiB,EAAE,cAAc,GAAG,IAAI,CAAC;IACzC;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B,KAAG,WAgBH,CAAC"}
1
+ {"version":3,"file":"sse_auth_guard.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/realtime/sse_auth_guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAGtD,OAAO,EAIN,KAAK,aAAa,EAClB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACxF,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAE3D,2DAA2D;AAC3D,eAAO,MAAM,iBAAiB,cAAc,CAAC;AAE7C;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,4BAA4B,GAAI,CAAC,EAC7C,UAAU,kBAAkB,CAAC,CAAC,CAAC,KAC7B,gBAKD,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,eAAO,MAAM,qBAAqB,GAAI,CAAC,EACtC,UAAU,kBAAkB,CAAC,CAAC,CAAC,EAC/B,eAAe,MAAM,GAAG,IAAI,EAC5B,KAAK,MAAM,KACT,CAAC,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CA4DjC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC3B;;;;;OAKG;IACH,QAAQ,EAAE,kBAAkB,CAAC,eAAe,CAAC,CAAC;IAC9C,kFAAkF;IAClF,GAAG,EAAE,MAAM,CAAC;IACZ,yJAAyJ;IACzJ,cAAc,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;CAC/C;AAED;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,EAAE,KAAK,CAAC,SAAS,CAOlD,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,2BAA2B,KAAK,CAAC;AAE9C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,eAAO,MAAM,oBAAoB,GAAI,SAAS;IAC7C,mEAAmE;IACnE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;;;;;OASG;IACH,iBAAiB,EAAE,cAAc,GAAG,IAAI,CAAC;IACzC;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B,KAAG,WAgBH,CAAC"}
@@ -164,7 +164,9 @@ export const AUDIT_LOG_SSE_MAX_PER_SCOPE = 10;
164
164
  * connection closer.
165
165
  *
166
166
  * Combines `SubscriberRegistry`, `create_sse_auth_guard`, and the broadcast
167
- * call into a single object, and adds the registry to `connection_closer`.
167
+ * call into a single object, and adds the registry to `connection_closer` for
168
+ * good — the remover `add` returns is dropped, so a caller that must take the
169
+ * registry out again passes `null` and adds it itself.
168
170
  * The result satisfies `AuditLogRouteOptions['stream']`
169
171
  * and provides the `on_audit_event` listener for the audit emitter.
170
172
  *
@@ -10,18 +10,18 @@
10
10
  import { Hono, type Context } from 'hono';
11
11
  import type { UpgradeWebSocket } from 'hono/ws';
12
12
  import { z } from 'zod';
13
- import { type SessionOptions } from '../auth/session_cookie.js';
13
+ import { type SessionOptions, type SessionCookieOptions } from '../auth/session_cookie.js';
14
14
  import type { BootstrapAccountSuccess } from '../auth/bootstrap_account.js';
15
15
  import type { EventSpec } from '../realtime/sse.js';
16
16
  import { type AuditLogSse } from '../realtime/sse_auth_guard.js';
17
- import { RateLimiter, type RateLimiterMode } from '../rate_limiter.js';
17
+ import { RateLimiter, type RateLimiterMode, type RateLimiterOptions } from '../rate_limiter.js';
18
18
  import type { DaemonTokenState } from '../auth/daemon_token.js';
19
19
  import type { MigrationResult } from '../db/migrate.js';
20
20
  import type { AppBackend } from './app_backend.js';
21
21
  import type { AppServerContext } from './app_server_context.js';
22
22
  import '../hono_context.js';
23
23
  import { type ServeStaticFactory } from './static.js';
24
- import { type AppSurfaceSpec, type RpcEndpointSpec } from '../http/surface.js';
24
+ import { type AppSurfaceSpec, type AppSurfaceDiagnostic, type RpcEndpointSpec } from '../http/surface.js';
25
25
  import { type RouteSpec } from '../http/route_spec.js';
26
26
  import type { MiddlewareSpec } from '../http/middleware_spec.js';
27
27
  import { type BootstrapStatus } from '../auth/bootstrap_routes.js';
@@ -186,10 +186,19 @@ export interface AppServerOptions {
186
186
  /** Bootstrap options. Omit to skip bootstrap status check and routes. */
187
187
  bootstrap?: BootstrapServerOptions;
188
188
  /**
189
- * Set to `false` to disable the auto-created surface route (`GET /api/surface`).
190
- * Default: auto-created (authenticated).
189
+ * Mount `GET /api/surface`, which serves this server's generated
190
+ * `AppSurface` (every route, its auth, and its schemas) to an admin UI such
191
+ * as `AdminSurface.svelte`. Off by default — the Rust spine serves no such
192
+ * route, and a map of the API is nothing to publish unasked.
193
+ *
194
+ * When mounted the route is admin-only (`roles: ['admin']`, so it takes the
195
+ * `?acting=` selector) and a rule-3 token surface
196
+ * (`required_scope: 'surface:app_surface'`): a narrowed API token is refused
197
+ * it whatever its method list says. See `server/surface_route.ts`.
198
+ *
199
+ * @default false
191
200
  */
192
- surface_route?: false;
201
+ surface_route?: boolean;
193
202
  /**
194
203
  * Build route specs from the initialized backend.
195
204
  * Called after all middleware is ready.
@@ -469,6 +478,106 @@ export declare const require_audit_sse: (source: {
469
478
  }) => AuditLogSse;
470
479
  /** Default maximum request body size: 1 MiB. */
471
480
  export declare const DEFAULT_MAX_BODY_SIZE: number;
481
+ /**
482
+ * Each `AppServerOptions` rate-limiter field, with the defaults an omitted one
483
+ * is built from under `rate_limiters: 'enforced'` and the name its
484
+ * explicitly-null diagnostic uses. Insertion order is the order limiters are
485
+ * built and their diagnostics are listed.
486
+ */
487
+ declare const rate_limiter_slots: {
488
+ readonly login_ip_rate_limiter: {
489
+ readonly label: "login IP";
490
+ readonly defaults: RateLimiterOptions;
491
+ };
492
+ readonly signup_ip_rate_limiter: {
493
+ readonly label: "signup IP";
494
+ readonly defaults: RateLimiterOptions;
495
+ };
496
+ readonly bootstrap_ip_rate_limiter: {
497
+ readonly label: "bootstrap IP";
498
+ readonly defaults: RateLimiterOptions;
499
+ };
500
+ readonly login_account_rate_limiter: {
501
+ readonly label: "login account";
502
+ readonly defaults: RateLimiterOptions;
503
+ };
504
+ readonly signup_account_rate_limiter: {
505
+ readonly label: "signup account";
506
+ readonly defaults: RateLimiterOptions;
507
+ };
508
+ readonly action_ip_rate_limiter: {
509
+ readonly label: "action IP";
510
+ readonly defaults: RateLimiterOptions;
511
+ };
512
+ readonly action_account_rate_limiter: {
513
+ readonly label: "action account";
514
+ readonly defaults: RateLimiterOptions;
515
+ };
516
+ };
517
+ /**
518
+ * Name of an `AppServerOptions` rate-limiter field — also the
519
+ * `AppServerContext` field its resolved limiter lands on.
520
+ *
521
+ * @internal
522
+ */
523
+ export type AppServerRateLimiterKey = keyof typeof rate_limiter_slots;
524
+ /**
525
+ * Every `AppServerOptions` rate-limiter field, in build order.
526
+ *
527
+ * @internal
528
+ */
529
+ export declare const APP_SERVER_RATE_LIMITER_KEYS: ReadonlyArray<AppServerRateLimiterKey>;
530
+ /**
531
+ * The rate limiters `create_app_server` resolved from its options.
532
+ *
533
+ * @internal
534
+ */
535
+ export interface ResolvedRateLimiters {
536
+ /** The `rate_limiters` mode, defaulted to `'enforced'`. */
537
+ mode: RateLimiterMode;
538
+ /** Each limiter by option name — `null` when off. */
539
+ limiters: Record<AppServerRateLimiterKey, RateLimiter | null>;
540
+ /**
541
+ * The limiters built here for omitted options, in build order — the
542
+ * server's to dispose. Never one passed in, which its caller owns.
543
+ */
544
+ built: Array<RateLimiter>;
545
+ }
546
+ /**
547
+ * Resolve each rate-limiter option: an explicit option (instance or `null`)
548
+ * wins; an omitted one is a default instance under `'enforced'` and `null`
549
+ * under `'disabled_for_testing'`, which also announces the mode on stderr
550
+ * (`announce_rate_limiters_disabled`). One instance per surface — see
551
+ * `AppServerOptions.login_ip_rate_limiter` for why these are not a single
552
+ * shared bucket.
553
+ *
554
+ * @param options - the rate-limiter fields and `rate_limiters` mode of `AppServerOptions`
555
+ * @internal
556
+ */
557
+ export declare const resolve_rate_limiters: (options: Pick<AppServerOptions, AppServerRateLimiterKey | "rate_limiters">) => ResolvedRateLimiters;
558
+ /**
559
+ * Inputs to `collect_config_diagnostics`.
560
+ *
561
+ * @internal
562
+ */
563
+ export interface ConfigDiagnosticsInput {
564
+ /** The session cookie overrides, from `AppServerOptions.session_options`. */
565
+ cookie_options: Partial<SessionCookieOptions> | undefined;
566
+ /** The `rate_limiters` mode, defaulted. */
567
+ rate_limiter_mode: RateLimiterMode;
568
+ /** The resolved limiters, from `resolve_rate_limiters`. */
569
+ rate_limiters: Record<AppServerRateLimiterKey, RateLimiter | null>;
570
+ }
571
+ /**
572
+ * The config-level diagnostics `create_app_server` appends to the surface's
573
+ * spec-level ones: a weakened session cookie, and an open rate-limited
574
+ * surface — one warning for `'disabled_for_testing'`, otherwise one per
575
+ * explicitly-null limiter, so a deployment that disables login's limiter but
576
+ * keeps signup's reads differently from one that disables both.
577
+ *
578
+ * @internal
579
+ */
580
+ export declare const collect_config_diagnostics: (input: ConfigDiagnosticsInput) => Array<AppSurfaceDiagnostic>;
472
581
  /**
473
582
  * Create a fully assembled Hono app with auth, middleware, and routes.
474
583
  *
@@ -503,8 +612,10 @@ export declare const DEFAULT_MAX_BODY_SIZE: number;
503
612
  * live connection on the backend's closer, runs the same releases, and
504
613
  * closes the database (`AppServer.close`).
505
614
  *
506
- * @returns assembled Hono app, backend, surface build, and bootstrap status
615
+ * @returns the assembled Hono app with its surface, bootstrap status, migration results,
616
+ * audit SSE, mounted WS transports, and `close`
507
617
  * @throws Error from any assembly step, after releasing what assembly acquired
508
618
  */
509
619
  export declare const create_app_server: (options: AppServerOptions) => Promise<AppServer>;
620
+ export {};
510
621
  //# sourceMappingURL=app_server.d.ts.map