@uptimizr/metrics 0.0.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.
@@ -0,0 +1,4119 @@
1
+ /**
2
+ * The semantic **metric registry** (ADR 0051 §1, design sketch §A).
3
+ *
4
+ * One {@link MetricDefinition} per `build*` aggregation in `@uptimizr/db`'s
5
+ * `query/aggregations.ts`, declaring what the metric measures, what one row *is*,
6
+ * the unit and semantics of every column, the filters it accepts, the collector
7
+ * endpoint it is served on, the capture channels that must be enabled for it to
8
+ * have data, and how to read the result. Downstream consumers (the agent tool
9
+ * catalog, OpenAPI, the MCP capabilities resource, the docs tables) are meant to
10
+ * be **derived** from this file rather than hand-maintained, so coverage cannot
11
+ * drift.
12
+ *
13
+ * **This module is pure data.** It imports `zod` and a *type-only* declaration
14
+ * from `@uptimizr/schema`; it performs no I/O, touches no `node:` built-in and
15
+ * holds no reference to a store, a dialect or a database driver. That is the
16
+ * whole reason this package exists: `@uptimizr/db` depends on `@duckdb/node-api`
17
+ * (a ~37 MB native binding), and the browser/CLI consumers of the registry
18
+ * (`@uptimizr/agent-core`, `@uptimizr/mcp`, `@uptimizr/react`) can never use a
19
+ * DuckDB driver — so the registry lives here, in a package whose only runtime
20
+ * dependencies are `zod` and `@uptimizr/schema`.
21
+ *
22
+ * **Numbers are numbers.** Every numeric column is a strict `z.number()`, so a
23
+ * `row` schema describes exactly what the collector emits. The engines that
24
+ * string-encode 64-bit integers or decimals (ClickHouse over HTTP) are
25
+ * normalised by `coerceRows` in every store's query runner, at the one point
26
+ * rows leave the driver (ADR 0051 §2, `query/coerce.ts`) — the schema is the
27
+ * contract, the store edge is what upholds it.
28
+ *
29
+ * The invariant this file exists to enforce: **a new aggregation is not done
30
+ * until it has a registry entry.** This package's `src/__tests__/registry.test.ts`
31
+ * fails the build when a name in {@link AGGREGATION_BUILDER_NAMES} has no entry;
32
+ * `@uptimizr/db`'s own `src/__tests__/registry.test.ts` fails when that list and
33
+ * the `build*` exports of `aggregations.ts` disagree; and the collector's
34
+ * `registryRoutes.test.ts` fails when an entry's endpoint or filters drift from
35
+ * the Zod querystring that actually serves it.
36
+ */
37
+ import { z } from "zod";
38
+ import type { EventType } from "@uptimizr/schema";
39
+ /**
40
+ * Every exported `build*` aggregation name in `@uptimizr/db`'s
41
+ * `query/aggregations.ts`. The registry must cover them all.
42
+ *
43
+ * Declared here as literal data rather than derived with
44
+ * `keyof typeof aggregations`, because deriving it would make this package
45
+ * depend on `@uptimizr/db` — exactly the edge (and the ~37 MB native DuckDB
46
+ * binding behind it) that this package exists to break. The link is not lost,
47
+ * only moved from the compiler to CI: `@uptimizr/db`'s `registry.test.ts`
48
+ * asserts at runtime that the set of its `build*` exports is exactly this list,
49
+ * so adding, renaming or deleting an aggregation without updating this list
50
+ * fails the build and names the offender.
51
+ */
52
+ export declare const AGGREGATION_BUILDER_NAMES: readonly ["buildAggregateTrajectories", "buildArPlacementAttempts", "buildArPlacementSurfaces", "buildArPlacementTimeToPlace", "buildBacktrackRatio", "buildBoundaryContacts", "buildBoundaryHeatmap", "buildBoundaryHeatmapStats", "buildCameraDirectionHeatmap", "buildCameraDistance", "buildCameraGestures", "buildCameraPositionHeatmap", "buildCapabilityChanges", "buildClickGazeRay", "buildCompileStalls", "buildDeadClicks", "buildDistinctScenes", "buildErrorHeatmap", "buildEventTypeCounts", "buildEventsDaily", "buildFlowHeatmap", "buildFpsHistogram", "buildFrameTimePercentiles", "buildFunnel", "buildGazeHeatmap", "buildGazeHeatmapStats", "buildGraphicsDiagnosticCounts", "buildHoverDwell", "buildInteractionsBySource", "buildJankRate", "buildListSessions", "buildLoadBounceFunnel", "buildMeshBlindSpots", "buildMeshDwell", "buildMeshInteractionKinds", "buildMeshUvHeatmap", "buildNavigationStats", "buildPerfByDevice", "buildPerfByScene", "buildPerfChurn", "buildPerfDaily", "buildPerfDistribution", "buildPerfHeatmap", "buildPerfSummary", "buildPointerHeatmap", "buildRageClicks", "buildReachability", "buildRenderScaleTruth", "buildRenderingTechnology", "buildResourcePercentiles", "buildResourceSummary", "buildSceneCoverage", "buildSceneRetention", "buildSessionTrajectory", "buildStabilityCounts", "buildTimeseries", "buildTopInputActions", "buildTopMeshes", "buildTopMeshesBySource", "buildTopMeshesTrend", "buildTrackingQuality", "buildVariantLeaderboard", "buildViewCoverageHistogram", "buildWorldHeatmap", "buildWorldHeatmapStats", "buildXrAbandonment", "buildXrLocomotionComfort", "buildXrRotationRate", "buildXrSourceUsage"];
53
+ /** Every exported `build*` aggregation name. The registry must cover them all. */
54
+ export type AggregationBuilderName = (typeof AGGREGATION_BUILDER_NAMES)[number];
55
+ /**
56
+ * Group-by dimensions a metric's rows can be keyed by. Closed union, declared
57
+ * once: the query DSL (ADR 0051 §3) will accept exactly this vocabulary, so it
58
+ * is restricted to columns the store *promotes* — a group-by on any of them
59
+ * renders identically on DuckDB, ClickHouse, Postgres and SQL Server.
60
+ */
61
+ export type DimensionId = "scene" | "session" | "mesh" | "name" | "source" | "event_type" | "cameraMode" | "device.engine" | "device.renderer" | "device.isMobile" | "device.browser" | "device.os";
62
+ /** Where each {@link DimensionId} reads from in the event model. */
63
+ export declare const DIMENSION_COLUMNS: Readonly<Record<DimensionId, string>>;
64
+ /**
65
+ * Every request parameter the query surface accepts. Closed union, declared
66
+ * once: a metric's `filters` are exactly the keys of the Zod querystring that
67
+ * serves its endpoint (asserted by the collector's registry route test), and the
68
+ * DSL will accept the same names.
69
+ */
70
+ export type FilterId = "since" | "until" | "scene" | "session" | "source" | "mesh" | "region" | "cameraMode" | "bins" | "limit" | "cellSize" | "interval" | "type" | "bucket" | "bucketMs" | "bucketSize" | "minRepeats" | "windowMs" | "fpsThreshold" | "stallMs" | "moveThreshold" | "rapidTurn" | "centerX" | "centerY" | "centerZ" | "severity" | "category" | "errorKind" | "groupByOrigin" | "originVoxel" | "steps" | "bands" | "variant" | "conversion" | "format";
71
+ /**
72
+ * The option interface (in `types.ts`) a {@link FilterId} feeds. `BuilderOptions`
73
+ * means the builder's own inline option bag rather than a shared interface.
74
+ */
75
+ export type FilterOptionInterface = "RangeOptions" | "SceneOptions" | "SourceOptions" | "SessionOptions" | "MeshOptions" | "RegionOptions" | "CameraModeOptions" | "TimeseriesOptions" | "ErrorHeatmapOptions" | "PerfChurnOptions" | "FunnelOptions" | "LoadBounceFunnelOptions" | "VariantLeaderboardOptions" | "BuilderOptions"
76
+ /**
77
+ * Not an aggregation option at all: the parameter is consumed by the
78
+ * collector's response layer and never reaches a builder. Only `format`
79
+ * (design sketch §B.1) uses it.
80
+ */
81
+ | "ResultEnvelope";
82
+ /** How one request parameter reaches the aggregation layer. */
83
+ export interface FilterTarget {
84
+ /** The option interface in `types.ts` this parameter is assigned to. */
85
+ option: FilterOptionInterface;
86
+ /** The field on that interface the collector assigns the value to. */
87
+ field: string;
88
+ /** What the parameter does, agent-facing. */
89
+ description: string;
90
+ }
91
+ /**
92
+ * The single mapping from a request parameter to the option field it drives.
93
+ * Consumers (docs generator, OpenAPI, the DSL) read filter semantics here rather
94
+ * than re-deriving them from the route handlers.
95
+ */
96
+ export declare const FILTER_TARGETS: Readonly<Record<FilterId, FilterTarget>>;
97
+ /** Physical meaning of a column's values. */
98
+ export type ColumnUnit = "count" | "sessions" | "ms" | "s" | "fps" | "ratio" | "percent" | "world-units" | "radians" | "bytes" | "epoch-ms" | "id" | "label" | "timestamp" | "index";
99
+ /** Per-column semantics used by summaries, comparisons and the docs tables. */
100
+ export interface ColumnSemantics {
101
+ description: string;
102
+ unit?: ColumnUnit;
103
+ /** For summaries: the column to rank by. At most one per metric. */
104
+ measure?: boolean;
105
+ /** For summaries: the column that names the row (mesh, scene, bucket…). */
106
+ label?: boolean;
107
+ /**
108
+ * For summaries of a `bucket`-grain metric: the **ordered** column the rows
109
+ * advance along (the time bucket, the day, the histogram bin, the funnel
110
+ * step). Exactly one per `bucket`-grain metric, and never set on any other
111
+ * grain — asserted in `src/__tests__/registry.test.ts`.
112
+ *
113
+ * It exists because `label` cannot double as the axis: `mesh_trend` is one row
114
+ * per (mesh, bucket) and labels its rows by `mesh`, so ordering by `label`
115
+ * would interleave series instead of walking time.
116
+ */
117
+ axis?: boolean;
118
+ /** Denominator column when this column is a rate/share. */
119
+ rateOf?: string;
120
+ }
121
+ /** What one row of a metric represents. */
122
+ export type MetricGrain = "project" | "scene" | "session" | "mesh" | "bin" | "voxel" | "bucket" | "row";
123
+ /** Grouping used by the docs, the capabilities resource and the health score. */
124
+ export type MetricCategory = "attention" | "interaction" | "navigation" | "performance" | "errors" | "xr" | "ar" | "sessions" | "conversion";
125
+ /** The collector route a metric is served on. */
126
+ export interface MetricEndpoint {
127
+ method: "GET";
128
+ /** Fastify path, `:param` placeholders included. */
129
+ path: string;
130
+ /**
131
+ * Filters carried in the path rather than the querystring (e.g. the session id
132
+ * of a trajectory). One entry per `:param` segment, in order.
133
+ */
134
+ pathParams?: readonly FilterId[];
135
+ }
136
+ /** Comparison semantics for `compare`, `movers` and `anomalies` (ADR 0051 §4). */
137
+ export interface MetricComparison {
138
+ /** The column whose change is "the" change for this metric. */
139
+ primary: string;
140
+ /** Whether a rise is good, bad, or merely informational. */
141
+ direction: "up" | "down" | "neutral";
142
+ /** Minimum denominator before a delta is worth reporting. */
143
+ minSample: number;
144
+ }
145
+ /**
146
+ * Everything a consumer needs to call a metric, read its result and judge how
147
+ * far to trust it.
148
+ */
149
+ export interface MetricDefinition {
150
+ /** Stable id, snake_case. Also the DSL `metric` name and the agent tool name. */
151
+ id: MetricId;
152
+ title: string;
153
+ /** What it measures and what one row is — agent-facing, one paragraph. */
154
+ description: string;
155
+ /**
156
+ * The aggregation builder that computes it. Omitted for **resource** entries
157
+ * (`session_meta`, `scene_representation`) which are store reads, not
158
+ * aggregations, but are part of the agent surface.
159
+ */
160
+ builder?: AggregationBuilderName;
161
+ /** The canned collector route, when one exists. */
162
+ endpoint?: MetricEndpoint;
163
+ /** What one row represents. */
164
+ grain: MetricGrain;
165
+ /** The dimension columns this metric's rows are keyed by. */
166
+ dimensions: readonly DimensionId[];
167
+ /** Accepted querystring parameters — exactly the endpoint's Zod keys. */
168
+ filters: readonly FilterId[];
169
+ /** Output row schema: the source for OpenAPI, tool output schemas and coercion. */
170
+ row: z.ZodObject;
171
+ /** Per-column semantics, keyed by column name. */
172
+ columns: Readonly<Record<string, ColumnSemantics>>;
173
+ /** Registry-declared caps, so no consumer can ask for an unbounded payload. */
174
+ limits: {
175
+ maxRows: number;
176
+ maxSummaryRows: number;
177
+ };
178
+ /** How to read the result. */
179
+ interpretation: string;
180
+ /** Small-sample, capture-gating and sampling-rate warnings. */
181
+ caveats: readonly string[];
182
+ /** The capture channels that feed it (ADR 0012) — empty for derived rollups. */
183
+ sourceChannels: readonly EventType[];
184
+ /** Metrics worth reading alongside this one. */
185
+ related: readonly MetricId[];
186
+ /** Comparison semantics, when the metric has a meaningful single measure. */
187
+ comparable?: MetricComparison;
188
+ category: MetricCategory;
189
+ }
190
+ /**
191
+ * Every metric id. Declared as a closed union (rather than inferred from the
192
+ * registry object) so `METRIC_REGISTRY` is checked for exhaustive coverage and
193
+ * `MetricDefinition.id` can reference it without a circular type.
194
+ *
195
+ * The first twenty ids are the tool names already shipped in
196
+ * `@uptimizr/agent-core` (`readTools`) and MUST NOT change — an MCP client that
197
+ * calls `top_meshes` today must keep working when the catalog is generated from
198
+ * this registry (design sketch §A.4).
199
+ */
200
+ export type MetricId = "list_sessions" | "pointer_heatmap" | "world_heatmap" | "camera_heatmap" | "click_rays" | "flow_links" | "top_meshes" | "perf_summary" | "list_scenes" | "timeseries" | "event_counts" | "session_meta" | "scene_representation" | "funnel" | "aggregate_paths" | "rendering_technology" | "xr_rotation" | "xr_sources" | "xr_abandonment" | "xr_locomotion" | "mesh_uv_heatmap" | "world_heatmap_stats" | "gaze_heatmap" | "gaze_heatmap_stats" | "view_coverage_histogram" | "position_heatmap" | "session_trajectory" | "scene_coverage" | "camera_distance" | "mesh_sources" | "mesh_trend" | "mesh_dwell" | "mesh_blind_spots" | "mesh_interaction_kinds" | "mesh_reachability" | "dead_clicks" | "rage_clicks" | "hover_dwell" | "interaction_sources" | "top_input_actions" | "camera_gestures" | "navigation_stats" | "backtrack_ratio" | "render_scale_truth" | "perf_distribution" | "fps_histogram" | "frame_time_percentiles" | "jank_rate" | "perf_churn" | "perf_by_device" | "perf_by_scene" | "perf_heatmap" | "perf_daily" | "events_daily" | "compile_stalls" | "resource_summary" | "resource_percentiles" | "stability_counts" | "graphics_diagnostics" | "error_heatmap" | "capability_changes" | "boundary_heatmap" | "boundary_heatmap_stats" | "xr_boundary_contacts" | "xr_tracking_quality" | "ar_placement_time_to_place" | "ar_placement_attempts" | "ar_placement_surfaces" | "scene_retention" | "load_bounce_funnel" | "variant_leaderboard";
201
+ /**
202
+ * The metric registry: one entry per `build*` aggregation, plus the two
203
+ * builder-less resource reads that are part of the agent surface.
204
+ *
205
+ * Declared with `satisfies` (not a type annotation) so each entry keeps its
206
+ * literal `builder` type — which is what makes the compile-time coverage guard
207
+ * at the bottom of this file work. The `Record<MetricId, …>` target makes a
208
+ * missing metric a type error.
209
+ */
210
+ export declare const METRIC_REGISTRY: {
211
+ list_sessions: {
212
+ id: "list_sessions";
213
+ title: string;
214
+ description: string;
215
+ builder: "buildListSessions";
216
+ endpoint: {
217
+ method: "GET";
218
+ path: string;
219
+ };
220
+ grain: "session";
221
+ dimensions: "session"[];
222
+ filters: ("cameraMode" | "since" | "until" | "bins" | "limit" | "format")[];
223
+ row: z.ZodObject<{
224
+ session_id: z.ZodString;
225
+ visitor_id: z.ZodString;
226
+ events: z.ZodNumber;
227
+ started_at: z.ZodString;
228
+ ended_at: z.ZodString;
229
+ }, z.core.$strip>;
230
+ columns: {
231
+ session_id: {
232
+ description: string;
233
+ unit: "id";
234
+ label: true;
235
+ };
236
+ visitor_id: {
237
+ description: string;
238
+ unit: "id";
239
+ };
240
+ events: {
241
+ description: string;
242
+ unit: "count";
243
+ measure: true;
244
+ };
245
+ started_at: {
246
+ description: string;
247
+ unit: "timestamp";
248
+ };
249
+ ended_at: {
250
+ description: string;
251
+ unit: "timestamp";
252
+ };
253
+ };
254
+ limits: {
255
+ maxRows: number;
256
+ maxSummaryRows: number;
257
+ };
258
+ interpretation: string;
259
+ caveats: string[];
260
+ sourceChannels: never[];
261
+ related: ("list_scenes" | "timeseries" | "session_meta")[];
262
+ comparable: {
263
+ primary: string;
264
+ direction: "neutral";
265
+ minSample: number;
266
+ };
267
+ category: "sessions";
268
+ };
269
+ session_meta: {
270
+ id: "session_meta";
271
+ title: string;
272
+ description: string;
273
+ endpoint: {
274
+ method: "GET";
275
+ path: string;
276
+ pathParams: "session"[];
277
+ };
278
+ grain: "session";
279
+ dimensions: "session"[];
280
+ filters: never[];
281
+ row: z.ZodObject<{
282
+ sessionId: z.ZodString;
283
+ startedAt: z.ZodOptional<z.ZodString>;
284
+ device: z.ZodOptional<z.ZodUnknown>;
285
+ scene: z.ZodOptional<z.ZodUnknown>;
286
+ user: z.ZodOptional<z.ZodUnknown>;
287
+ }, z.core.$strip>;
288
+ columns: {
289
+ sessionId: {
290
+ description: string;
291
+ unit: "id";
292
+ label: true;
293
+ };
294
+ startedAt: {
295
+ description: string;
296
+ unit: "timestamp";
297
+ };
298
+ device: {
299
+ description: string;
300
+ };
301
+ scene: {
302
+ description: string;
303
+ };
304
+ user: {
305
+ description: string;
306
+ };
307
+ };
308
+ limits: {
309
+ maxRows: number;
310
+ maxSummaryRows: number;
311
+ };
312
+ interpretation: string;
313
+ caveats: string[];
314
+ sourceChannels: "session_start"[];
315
+ related: ("list_sessions" | "perf_by_device")[];
316
+ category: "sessions";
317
+ };
318
+ scene_representation: {
319
+ id: "scene_representation";
320
+ title: string;
321
+ description: string;
322
+ endpoint: {
323
+ method: "GET";
324
+ path: string;
325
+ pathParams: "scene"[];
326
+ };
327
+ grain: "scene";
328
+ dimensions: "scene"[];
329
+ filters: never[];
330
+ row: z.ZodObject<{
331
+ projectId: z.ZodString;
332
+ sceneId: z.ZodString;
333
+ label: z.ZodNullable<z.ZodString>;
334
+ kind: z.ZodString;
335
+ upAxis: z.ZodString;
336
+ unitScale: z.ZodNumber;
337
+ bounds: z.ZodNullable<z.ZodArray<z.ZodNumber>>;
338
+ proxy: z.ZodNullable<z.ZodUnknown>;
339
+ assetUrl: z.ZodNullable<z.ZodString>;
340
+ contentHash: z.ZodNullable<z.ZodString>;
341
+ proxyVersion: z.ZodNullable<z.ZodNumber>;
342
+ capturedAt: z.ZodNullable<z.ZodUnknown>;
343
+ updatedAt: z.ZodUnknown;
344
+ }, z.core.$strip>;
345
+ columns: {
346
+ projectId: {
347
+ description: string;
348
+ unit: "id";
349
+ };
350
+ sceneId: {
351
+ description: string;
352
+ unit: "id";
353
+ label: true;
354
+ };
355
+ label: {
356
+ description: string;
357
+ unit: "label";
358
+ };
359
+ kind: {
360
+ description: string;
361
+ unit: "label";
362
+ };
363
+ upAxis: {
364
+ description: string;
365
+ unit: "label";
366
+ };
367
+ unitScale: {
368
+ description: string;
369
+ unit: "ratio";
370
+ };
371
+ bounds: {
372
+ description: string;
373
+ unit: "world-units";
374
+ };
375
+ proxy: {
376
+ description: string;
377
+ };
378
+ assetUrl: {
379
+ description: string;
380
+ };
381
+ contentHash: {
382
+ description: string;
383
+ unit: "id";
384
+ };
385
+ proxyVersion: {
386
+ description: string;
387
+ unit: "index";
388
+ };
389
+ capturedAt: {
390
+ description: string;
391
+ unit: "timestamp";
392
+ };
393
+ updatedAt: {
394
+ description: string;
395
+ unit: "timestamp";
396
+ };
397
+ };
398
+ limits: {
399
+ maxRows: number;
400
+ maxSummaryRows: number;
401
+ };
402
+ interpretation: string;
403
+ caveats: string[];
404
+ sourceChannels: never[];
405
+ related: ("world_heatmap" | "list_scenes" | "gaze_heatmap" | "scene_coverage")[];
406
+ category: "sessions";
407
+ };
408
+ list_scenes: {
409
+ id: "list_scenes";
410
+ title: string;
411
+ description: string;
412
+ builder: "buildDistinctScenes";
413
+ endpoint: {
414
+ method: "GET";
415
+ path: string;
416
+ };
417
+ grain: "scene";
418
+ dimensions: "scene"[];
419
+ filters: ("since" | "until" | "limit" | "format")[];
420
+ row: z.ZodObject<{
421
+ scene_id: z.ZodString;
422
+ events: z.ZodNumber;
423
+ last_seen: z.ZodString;
424
+ }, z.core.$strip>;
425
+ columns: {
426
+ scene_id: {
427
+ description: string;
428
+ unit: "id";
429
+ label: true;
430
+ };
431
+ events: {
432
+ description: string;
433
+ unit: "count";
434
+ measure: true;
435
+ };
436
+ last_seen: {
437
+ description: string;
438
+ unit: "timestamp";
439
+ };
440
+ };
441
+ limits: {
442
+ maxRows: number;
443
+ maxSummaryRows: number;
444
+ };
445
+ interpretation: string;
446
+ caveats: string[];
447
+ sourceChannels: never[];
448
+ related: ("scene_representation" | "perf_by_scene" | "scene_retention")[];
449
+ comparable: {
450
+ primary: string;
451
+ direction: "neutral";
452
+ minSample: number;
453
+ };
454
+ category: "sessions";
455
+ };
456
+ timeseries: {
457
+ id: "timeseries";
458
+ title: string;
459
+ description: string;
460
+ builder: "buildTimeseries";
461
+ endpoint: {
462
+ method: "GET";
463
+ path: string;
464
+ };
465
+ grain: "bucket";
466
+ dimensions: ("scene" | "event_type")[];
467
+ filters: ("scene" | "since" | "until" | "interval" | "type" | "format")[];
468
+ row: z.ZodObject<{
469
+ bucket: z.ZodNumber;
470
+ events: z.ZodNumber;
471
+ avg_fps: z.ZodNumber;
472
+ }, z.core.$strip>;
473
+ columns: {
474
+ bucket: {
475
+ description: string;
476
+ unit: "epoch-ms";
477
+ label: true;
478
+ axis: true;
479
+ };
480
+ events: {
481
+ description: string;
482
+ unit: "count";
483
+ measure: true;
484
+ };
485
+ avg_fps: {
486
+ description: string;
487
+ unit: "fps";
488
+ };
489
+ };
490
+ limits: {
491
+ maxRows: number;
492
+ maxSummaryRows: number;
493
+ };
494
+ interpretation: string;
495
+ caveats: string[];
496
+ sourceChannels: "frame_perf"[];
497
+ related: ("event_counts" | "perf_distribution" | "events_daily")[];
498
+ comparable: {
499
+ primary: string;
500
+ direction: "neutral";
501
+ minSample: number;
502
+ };
503
+ category: "sessions";
504
+ };
505
+ event_counts: {
506
+ id: "event_counts";
507
+ title: string;
508
+ description: string;
509
+ builder: "buildEventTypeCounts";
510
+ endpoint: {
511
+ method: "GET";
512
+ path: string;
513
+ };
514
+ grain: "row";
515
+ dimensions: ("scene" | "event_type")[];
516
+ filters: ("scene" | "since" | "until" | "format")[];
517
+ row: z.ZodObject<{
518
+ event_type: z.ZodString;
519
+ count: z.ZodNumber;
520
+ }, z.core.$strip>;
521
+ columns: {
522
+ event_type: {
523
+ description: string;
524
+ unit: "label";
525
+ label: true;
526
+ };
527
+ count: {
528
+ description: string;
529
+ unit: "count";
530
+ measure: true;
531
+ };
532
+ };
533
+ limits: {
534
+ maxRows: number;
535
+ maxSummaryRows: number;
536
+ };
537
+ interpretation: string;
538
+ caveats: string[];
539
+ sourceChannels: never[];
540
+ related: ("timeseries" | "events_daily" | "stability_counts")[];
541
+ comparable: {
542
+ primary: string;
543
+ direction: "neutral";
544
+ minSample: number;
545
+ };
546
+ category: "sessions";
547
+ };
548
+ events_daily: {
549
+ id: "events_daily";
550
+ title: string;
551
+ description: string;
552
+ builder: "buildEventsDaily";
553
+ grain: "bucket";
554
+ dimensions: "event_type"[];
555
+ filters: never[];
556
+ row: z.ZodObject<{
557
+ day: z.ZodString;
558
+ event_type: z.ZodString;
559
+ events: z.ZodNumber;
560
+ }, z.core.$strip>;
561
+ columns: {
562
+ day: {
563
+ description: string;
564
+ unit: "label";
565
+ label: true;
566
+ axis: true;
567
+ };
568
+ event_type: {
569
+ description: string;
570
+ unit: "label";
571
+ };
572
+ events: {
573
+ description: string;
574
+ unit: "count";
575
+ measure: true;
576
+ };
577
+ };
578
+ limits: {
579
+ maxRows: number;
580
+ maxSummaryRows: number;
581
+ };
582
+ interpretation: string;
583
+ caveats: string[];
584
+ sourceChannels: never[];
585
+ related: ("timeseries" | "event_counts" | "perf_daily")[];
586
+ comparable: {
587
+ primary: string;
588
+ direction: "neutral";
589
+ minSample: number;
590
+ };
591
+ category: "sessions";
592
+ };
593
+ pointer_heatmap: {
594
+ id: "pointer_heatmap";
595
+ title: string;
596
+ description: string;
597
+ builder: "buildPointerHeatmap";
598
+ endpoint: {
599
+ method: "GET";
600
+ path: string;
601
+ };
602
+ grain: "bin";
603
+ dimensions: ("scene" | "session" | "source" | "cameraMode")[];
604
+ filters: ("scene" | "session" | "source" | "cameraMode" | "since" | "until" | "bins" | "limit" | "format")[];
605
+ row: z.ZodObject<{
606
+ gx: z.ZodNumber;
607
+ gy: z.ZodNumber;
608
+ count: z.ZodNumber;
609
+ }, z.core.$strip>;
610
+ columns: {
611
+ gx: {
612
+ description: string;
613
+ unit: "index";
614
+ label: true;
615
+ };
616
+ gy: {
617
+ description: string;
618
+ unit: "index";
619
+ };
620
+ count: {
621
+ description: string;
622
+ unit: "count";
623
+ measure: true;
624
+ };
625
+ };
626
+ limits: {
627
+ maxRows: number;
628
+ maxSummaryRows: number;
629
+ };
630
+ interpretation: string;
631
+ caveats: string[];
632
+ sourceChannels: ("pointer_move" | "pointer_click")[];
633
+ related: ("world_heatmap" | "click_rays" | "top_meshes" | "mesh_uv_heatmap")[];
634
+ comparable: {
635
+ primary: string;
636
+ direction: "neutral";
637
+ minSample: number;
638
+ };
639
+ category: "attention";
640
+ };
641
+ mesh_uv_heatmap: {
642
+ id: "mesh_uv_heatmap";
643
+ title: string;
644
+ description: string;
645
+ builder: "buildMeshUvHeatmap";
646
+ endpoint: {
647
+ method: "GET";
648
+ path: string;
649
+ };
650
+ grain: "bin";
651
+ dimensions: ("scene" | "session" | "mesh" | "source")[];
652
+ filters: ("scene" | "session" | "mesh" | "source" | "since" | "until" | "bins" | "limit" | "format")[];
653
+ row: z.ZodObject<{
654
+ gx: z.ZodNumber;
655
+ gy: z.ZodNumber;
656
+ count: z.ZodNumber;
657
+ }, z.core.$strip>;
658
+ columns: {
659
+ gx: {
660
+ description: string;
661
+ unit: "index";
662
+ label: true;
663
+ };
664
+ gy: {
665
+ description: string;
666
+ unit: "index";
667
+ };
668
+ count: {
669
+ description: string;
670
+ unit: "count";
671
+ measure: true;
672
+ };
673
+ };
674
+ limits: {
675
+ maxRows: number;
676
+ maxSummaryRows: number;
677
+ };
678
+ interpretation: string;
679
+ caveats: string[];
680
+ sourceChannels: ("hover_dwell" | "pointer_click" | "mesh_interaction")[];
681
+ related: ("pointer_heatmap" | "top_meshes" | "mesh_interaction_kinds")[];
682
+ comparable: {
683
+ primary: string;
684
+ direction: "neutral";
685
+ minSample: number;
686
+ };
687
+ category: "attention";
688
+ };
689
+ world_heatmap: {
690
+ id: "world_heatmap";
691
+ title: string;
692
+ description: string;
693
+ builder: "buildWorldHeatmap";
694
+ endpoint: {
695
+ method: "GET";
696
+ path: string;
697
+ };
698
+ grain: "voxel";
699
+ dimensions: ("scene" | "source" | "cameraMode")[];
700
+ filters: ("scene" | "source" | "cameraMode" | "since" | "until" | "region" | "limit" | "cellSize" | "format")[];
701
+ row: z.ZodObject<{
702
+ vx: z.ZodNumber;
703
+ vy: z.ZodNumber;
704
+ vz: z.ZodNumber;
705
+ count: z.ZodNumber;
706
+ }, z.core.$strip>;
707
+ columns: {
708
+ vx: {
709
+ description: string;
710
+ unit: "index";
711
+ label: true;
712
+ };
713
+ vy: {
714
+ description: string;
715
+ unit: "index";
716
+ };
717
+ vz: {
718
+ description: string;
719
+ unit: "index";
720
+ };
721
+ count: {
722
+ description: string;
723
+ unit: "count";
724
+ measure: true;
725
+ };
726
+ };
727
+ limits: {
728
+ maxRows: number;
729
+ maxSummaryRows: number;
730
+ };
731
+ interpretation: string;
732
+ caveats: string[];
733
+ sourceChannels: ("pointer_move" | "pointer_click")[];
734
+ related: ("pointer_heatmap" | "click_rays" | "world_heatmap_stats" | "gaze_heatmap")[];
735
+ comparable: {
736
+ primary: string;
737
+ direction: "neutral";
738
+ minSample: number;
739
+ };
740
+ category: "attention";
741
+ };
742
+ world_heatmap_stats: {
743
+ id: "world_heatmap_stats";
744
+ title: string;
745
+ description: string;
746
+ builder: "buildWorldHeatmapStats";
747
+ endpoint: {
748
+ method: "GET";
749
+ path: string;
750
+ };
751
+ grain: "project";
752
+ dimensions: ("scene" | "source" | "cameraMode")[];
753
+ filters: ("scene" | "source" | "cameraMode" | "since" | "until" | "region" | "cellSize" | "format")[];
754
+ row: z.ZodObject<{
755
+ cells: z.ZodNumber;
756
+ hits: z.ZodNumber;
757
+ }, z.core.$strip>;
758
+ columns: {
759
+ cells: {
760
+ description: string;
761
+ unit: "count";
762
+ };
763
+ hits: {
764
+ description: string;
765
+ unit: "count";
766
+ measure: true;
767
+ };
768
+ };
769
+ limits: {
770
+ maxRows: number;
771
+ maxSummaryRows: number;
772
+ };
773
+ interpretation: string;
774
+ caveats: string[];
775
+ sourceChannels: ("pointer_move" | "pointer_click")[];
776
+ related: "world_heatmap"[];
777
+ category: "attention";
778
+ };
779
+ gaze_heatmap: {
780
+ id: "gaze_heatmap";
781
+ title: string;
782
+ description: string;
783
+ builder: "buildGazeHeatmap";
784
+ endpoint: {
785
+ method: "GET";
786
+ path: string;
787
+ };
788
+ grain: "voxel";
789
+ dimensions: ("scene" | "session" | "cameraMode")[];
790
+ filters: ("scene" | "session" | "cameraMode" | "since" | "until" | "region" | "limit" | "cellSize" | "format")[];
791
+ row: z.ZodObject<{
792
+ vx: z.ZodNumber;
793
+ vy: z.ZodNumber;
794
+ vz: z.ZodNumber;
795
+ count: z.ZodNumber;
796
+ }, z.core.$strip>;
797
+ columns: {
798
+ vx: {
799
+ description: string;
800
+ unit: "index";
801
+ label: true;
802
+ };
803
+ vy: {
804
+ description: string;
805
+ unit: "index";
806
+ };
807
+ vz: {
808
+ description: string;
809
+ unit: "index";
810
+ };
811
+ count: {
812
+ description: string;
813
+ unit: "count";
814
+ measure: true;
815
+ };
816
+ };
817
+ limits: {
818
+ maxRows: number;
819
+ maxSummaryRows: number;
820
+ };
821
+ interpretation: string;
822
+ caveats: string[];
823
+ sourceChannels: "camera_sample"[];
824
+ related: ("world_heatmap" | "camera_heatmap" | "gaze_heatmap_stats" | "mesh_blind_spots")[];
825
+ comparable: {
826
+ primary: string;
827
+ direction: "neutral";
828
+ minSample: number;
829
+ };
830
+ category: "attention";
831
+ };
832
+ gaze_heatmap_stats: {
833
+ id: "gaze_heatmap_stats";
834
+ title: string;
835
+ description: string;
836
+ builder: "buildGazeHeatmapStats";
837
+ endpoint: {
838
+ method: "GET";
839
+ path: string;
840
+ };
841
+ grain: "project";
842
+ dimensions: ("scene" | "session" | "cameraMode")[];
843
+ filters: ("scene" | "session" | "cameraMode" | "since" | "until" | "region" | "cellSize" | "format")[];
844
+ row: z.ZodObject<{
845
+ cells: z.ZodNumber;
846
+ hits: z.ZodNumber;
847
+ }, z.core.$strip>;
848
+ columns: {
849
+ cells: {
850
+ description: string;
851
+ unit: "count";
852
+ };
853
+ hits: {
854
+ description: string;
855
+ unit: "count";
856
+ measure: true;
857
+ };
858
+ };
859
+ limits: {
860
+ maxRows: number;
861
+ maxSummaryRows: number;
862
+ };
863
+ interpretation: string;
864
+ caveats: string[];
865
+ sourceChannels: "camera_sample"[];
866
+ related: "gaze_heatmap"[];
867
+ category: "attention";
868
+ };
869
+ camera_heatmap: {
870
+ id: "camera_heatmap";
871
+ title: string;
872
+ description: string;
873
+ builder: "buildCameraDirectionHeatmap";
874
+ endpoint: {
875
+ method: "GET";
876
+ path: string;
877
+ };
878
+ grain: "bin";
879
+ dimensions: ("scene" | "session" | "cameraMode")[];
880
+ filters: ("scene" | "session" | "cameraMode" | "since" | "until" | "bins" | "limit" | "format")[];
881
+ row: z.ZodObject<{
882
+ azimuth_bin: z.ZodNumber;
883
+ elevation_bin: z.ZodNumber;
884
+ count: z.ZodNumber;
885
+ }, z.core.$strip>;
886
+ columns: {
887
+ azimuth_bin: {
888
+ description: string;
889
+ unit: "index";
890
+ label: true;
891
+ };
892
+ elevation_bin: {
893
+ description: string;
894
+ unit: "index";
895
+ };
896
+ count: {
897
+ description: string;
898
+ unit: "count";
899
+ measure: true;
900
+ };
901
+ };
902
+ limits: {
903
+ maxRows: number;
904
+ maxSummaryRows: number;
905
+ };
906
+ interpretation: string;
907
+ caveats: string[];
908
+ sourceChannels: "camera_sample"[];
909
+ related: ("flow_links" | "gaze_heatmap" | "view_coverage_histogram")[];
910
+ comparable: {
911
+ primary: string;
912
+ direction: "neutral";
913
+ minSample: number;
914
+ };
915
+ category: "attention";
916
+ };
917
+ view_coverage_histogram: {
918
+ id: "view_coverage_histogram";
919
+ title: string;
920
+ description: string;
921
+ builder: "buildViewCoverageHistogram";
922
+ endpoint: {
923
+ method: "GET";
924
+ path: string;
925
+ };
926
+ grain: "bucket";
927
+ dimensions: ("scene" | "session" | "cameraMode")[];
928
+ filters: ("scene" | "session" | "cameraMode" | "since" | "until" | "bins" | "limit" | "format")[];
929
+ row: z.ZodObject<{
930
+ bucket: z.ZodNumber;
931
+ sessions: z.ZodNumber;
932
+ }, z.core.$strip>;
933
+ columns: {
934
+ bucket: {
935
+ description: string;
936
+ unit: "percent";
937
+ label: true;
938
+ axis: true;
939
+ };
940
+ sessions: {
941
+ description: string;
942
+ unit: "sessions";
943
+ measure: true;
944
+ };
945
+ };
946
+ limits: {
947
+ maxRows: number;
948
+ maxSummaryRows: number;
949
+ };
950
+ interpretation: string;
951
+ caveats: string[];
952
+ sourceChannels: "camera_sample"[];
953
+ related: ("camera_heatmap" | "gaze_heatmap" | "scene_coverage")[];
954
+ comparable: {
955
+ primary: string;
956
+ direction: "neutral";
957
+ minSample: number;
958
+ };
959
+ category: "attention";
960
+ };
961
+ position_heatmap: {
962
+ id: "position_heatmap";
963
+ title: string;
964
+ description: string;
965
+ builder: "buildCameraPositionHeatmap";
966
+ endpoint: {
967
+ method: "GET";
968
+ path: string;
969
+ };
970
+ grain: "bin";
971
+ dimensions: ("scene" | "session" | "cameraMode")[];
972
+ filters: ("scene" | "session" | "cameraMode" | "since" | "until" | "region" | "limit" | "cellSize" | "format")[];
973
+ row: z.ZodObject<{
974
+ gx: z.ZodNumber;
975
+ gz: z.ZodNumber;
976
+ avg_y: z.ZodNumber;
977
+ count: z.ZodNumber;
978
+ }, z.core.$strip>;
979
+ columns: {
980
+ gx: {
981
+ description: string;
982
+ unit: "index";
983
+ label: true;
984
+ };
985
+ gz: {
986
+ description: string;
987
+ unit: "index";
988
+ };
989
+ avg_y: {
990
+ description: string;
991
+ unit: "world-units";
992
+ };
993
+ count: {
994
+ description: string;
995
+ unit: "count";
996
+ measure: true;
997
+ };
998
+ };
999
+ limits: {
1000
+ maxRows: number;
1001
+ maxSummaryRows: number;
1002
+ };
1003
+ interpretation: string;
1004
+ caveats: string[];
1005
+ sourceChannels: "camera_sample"[];
1006
+ related: ("aggregate_paths" | "scene_coverage" | "navigation_stats" | "backtrack_ratio")[];
1007
+ comparable: {
1008
+ primary: string;
1009
+ direction: "neutral";
1010
+ minSample: number;
1011
+ };
1012
+ category: "navigation";
1013
+ };
1014
+ session_trajectory: {
1015
+ id: "session_trajectory";
1016
+ title: string;
1017
+ description: string;
1018
+ builder: "buildSessionTrajectory";
1019
+ endpoint: {
1020
+ method: "GET";
1021
+ path: string;
1022
+ pathParams: "session"[];
1023
+ };
1024
+ grain: "row";
1025
+ dimensions: ("scene" | "session")[];
1026
+ filters: ("scene" | "since" | "until" | "limit" | "format")[];
1027
+ row: z.ZodObject<{
1028
+ ts: z.ZodNumber;
1029
+ x: z.ZodNumber;
1030
+ y: z.ZodNumber;
1031
+ z: z.ZodNumber;
1032
+ }, z.core.$strip>;
1033
+ columns: {
1034
+ ts: {
1035
+ description: string;
1036
+ unit: "epoch-ms";
1037
+ label: true;
1038
+ };
1039
+ x: {
1040
+ description: string;
1041
+ unit: "world-units";
1042
+ };
1043
+ y: {
1044
+ description: string;
1045
+ unit: "world-units";
1046
+ };
1047
+ z: {
1048
+ description: string;
1049
+ unit: "world-units";
1050
+ };
1051
+ };
1052
+ limits: {
1053
+ maxRows: number;
1054
+ maxSummaryRows: number;
1055
+ };
1056
+ interpretation: string;
1057
+ caveats: string[];
1058
+ sourceChannels: "camera_sample"[];
1059
+ related: ("aggregate_paths" | "position_heatmap" | "navigation_stats")[];
1060
+ category: "navigation";
1061
+ };
1062
+ aggregate_paths: {
1063
+ id: "aggregate_paths";
1064
+ title: string;
1065
+ description: string;
1066
+ builder: "buildAggregateTrajectories";
1067
+ endpoint: {
1068
+ method: "GET";
1069
+ path: string;
1070
+ };
1071
+ grain: "row";
1072
+ dimensions: ("scene" | "session" | "cameraMode")[];
1073
+ filters: ("scene" | "cameraMode" | "since" | "until" | "limit" | "cellSize" | "format")[];
1074
+ row: z.ZodObject<{
1075
+ session_id: z.ZodString;
1076
+ ts: z.ZodNumber;
1077
+ gx: z.ZodNumber;
1078
+ gz: z.ZodNumber;
1079
+ }, z.core.$strip>;
1080
+ columns: {
1081
+ session_id: {
1082
+ description: string;
1083
+ unit: "id";
1084
+ label: true;
1085
+ };
1086
+ ts: {
1087
+ description: string;
1088
+ unit: "epoch-ms";
1089
+ };
1090
+ gx: {
1091
+ description: string;
1092
+ unit: "index";
1093
+ };
1094
+ gz: {
1095
+ description: string;
1096
+ unit: "index";
1097
+ };
1098
+ };
1099
+ limits: {
1100
+ maxRows: number;
1101
+ maxSummaryRows: number;
1102
+ };
1103
+ interpretation: string;
1104
+ caveats: string[];
1105
+ sourceChannels: "camera_sample"[];
1106
+ related: ("position_heatmap" | "session_trajectory" | "backtrack_ratio")[];
1107
+ category: "navigation";
1108
+ };
1109
+ scene_coverage: {
1110
+ id: "scene_coverage";
1111
+ title: string;
1112
+ description: string;
1113
+ builder: "buildSceneCoverage";
1114
+ endpoint: {
1115
+ method: "GET";
1116
+ path: string;
1117
+ };
1118
+ grain: "voxel";
1119
+ dimensions: ("scene" | "session")[];
1120
+ filters: ("scene" | "session" | "since" | "until" | "limit" | "cellSize" | "format")[];
1121
+ row: z.ZodObject<{
1122
+ vx: z.ZodNumber;
1123
+ vy: z.ZodNumber;
1124
+ vz: z.ZodNumber;
1125
+ count: z.ZodNumber;
1126
+ }, z.core.$strip>;
1127
+ columns: {
1128
+ vx: {
1129
+ description: string;
1130
+ unit: "index";
1131
+ label: true;
1132
+ };
1133
+ vy: {
1134
+ description: string;
1135
+ unit: "index";
1136
+ };
1137
+ vz: {
1138
+ description: string;
1139
+ unit: "index";
1140
+ };
1141
+ count: {
1142
+ description: string;
1143
+ unit: "count";
1144
+ measure: true;
1145
+ };
1146
+ };
1147
+ limits: {
1148
+ maxRows: number;
1149
+ maxSummaryRows: number;
1150
+ };
1151
+ interpretation: string;
1152
+ caveats: string[];
1153
+ sourceChannels: "camera_sample"[];
1154
+ related: ("scene_representation" | "view_coverage_histogram" | "position_heatmap")[];
1155
+ comparable: {
1156
+ primary: string;
1157
+ direction: "neutral";
1158
+ minSample: number;
1159
+ };
1160
+ category: "navigation";
1161
+ };
1162
+ camera_distance: {
1163
+ id: "camera_distance";
1164
+ title: string;
1165
+ description: string;
1166
+ builder: "buildCameraDistance";
1167
+ endpoint: {
1168
+ method: "GET";
1169
+ path: string;
1170
+ };
1171
+ grain: "bucket";
1172
+ dimensions: ("scene" | "session")[];
1173
+ filters: ("scene" | "session" | "since" | "until" | "limit" | "bucketSize" | "centerX" | "centerY" | "centerZ" | "format")[];
1174
+ row: z.ZodObject<{
1175
+ bucket: z.ZodNumber;
1176
+ count: z.ZodNumber;
1177
+ }, z.core.$strip>;
1178
+ columns: {
1179
+ bucket: {
1180
+ description: string;
1181
+ unit: "index";
1182
+ label: true;
1183
+ axis: true;
1184
+ };
1185
+ count: {
1186
+ description: string;
1187
+ unit: "count";
1188
+ measure: true;
1189
+ };
1190
+ };
1191
+ limits: {
1192
+ maxRows: number;
1193
+ maxSummaryRows: number;
1194
+ };
1195
+ interpretation: string;
1196
+ caveats: string[];
1197
+ sourceChannels: "camera_sample"[];
1198
+ related: ("position_heatmap" | "scene_coverage" | "camera_gestures")[];
1199
+ category: "navigation";
1200
+ };
1201
+ click_rays: {
1202
+ id: "click_rays";
1203
+ title: string;
1204
+ description: string;
1205
+ builder: "buildClickGazeRay";
1206
+ endpoint: {
1207
+ method: "GET";
1208
+ path: string;
1209
+ };
1210
+ grain: "voxel";
1211
+ dimensions: ("scene" | "session" | "mesh" | "source")[];
1212
+ filters: ("scene" | "session" | "source" | "since" | "until" | "limit" | "cellSize" | "format")[];
1213
+ row: z.ZodObject<{
1214
+ cam_vx: z.ZodNumber;
1215
+ cam_vy: z.ZodNumber;
1216
+ cam_vz: z.ZodNumber;
1217
+ origin_x: z.ZodNumber;
1218
+ origin_y: z.ZodNumber;
1219
+ origin_z: z.ZodNumber;
1220
+ hit_vx: z.ZodNumber;
1221
+ hit_vy: z.ZodNumber;
1222
+ hit_vz: z.ZodNumber;
1223
+ hit_x: z.ZodNumber;
1224
+ hit_y: z.ZodNumber;
1225
+ hit_z: z.ZodNumber;
1226
+ mesh: z.ZodString;
1227
+ count: z.ZodNumber;
1228
+ }, z.core.$strip>;
1229
+ columns: {
1230
+ cam_vx: {
1231
+ description: string;
1232
+ unit: "index";
1233
+ };
1234
+ cam_vy: {
1235
+ description: string;
1236
+ unit: "index";
1237
+ };
1238
+ cam_vz: {
1239
+ description: string;
1240
+ unit: "index";
1241
+ };
1242
+ origin_x: {
1243
+ description: string;
1244
+ unit: "world-units";
1245
+ };
1246
+ origin_y: {
1247
+ description: string;
1248
+ unit: "world-units";
1249
+ };
1250
+ origin_z: {
1251
+ description: string;
1252
+ unit: "world-units";
1253
+ };
1254
+ hit_vx: {
1255
+ description: string;
1256
+ unit: "index";
1257
+ };
1258
+ hit_vy: {
1259
+ description: string;
1260
+ unit: "index";
1261
+ };
1262
+ hit_vz: {
1263
+ description: string;
1264
+ unit: "index";
1265
+ };
1266
+ hit_x: {
1267
+ description: string;
1268
+ unit: "world-units";
1269
+ };
1270
+ hit_y: {
1271
+ description: string;
1272
+ unit: "world-units";
1273
+ };
1274
+ hit_z: {
1275
+ description: string;
1276
+ unit: "world-units";
1277
+ };
1278
+ mesh: {
1279
+ description: string;
1280
+ unit: "label";
1281
+ label: true;
1282
+ };
1283
+ count: {
1284
+ description: string;
1285
+ unit: "count";
1286
+ measure: true;
1287
+ };
1288
+ };
1289
+ limits: {
1290
+ maxRows: number;
1291
+ maxSummaryRows: number;
1292
+ };
1293
+ interpretation: string;
1294
+ caveats: string[];
1295
+ sourceChannels: ("camera_sample" | "pointer_click")[];
1296
+ related: ("world_heatmap" | "flow_links" | "top_meshes" | "mesh_reachability")[];
1297
+ comparable: {
1298
+ primary: string;
1299
+ direction: "neutral";
1300
+ minSample: number;
1301
+ };
1302
+ category: "interaction";
1303
+ };
1304
+ flow_links: {
1305
+ id: "flow_links";
1306
+ title: string;
1307
+ description: string;
1308
+ builder: "buildFlowHeatmap";
1309
+ endpoint: {
1310
+ method: "GET";
1311
+ path: string;
1312
+ };
1313
+ grain: "bin";
1314
+ dimensions: ("scene" | "session" | "mesh" | "cameraMode")[];
1315
+ filters: ("scene" | "session" | "cameraMode" | "since" | "until" | "bins" | "limit" | "cellSize" | "groupByOrigin" | "originVoxel" | "format")[];
1316
+ row: z.ZodObject<{
1317
+ azimuth_bin: z.ZodNumber;
1318
+ elevation_bin: z.ZodNumber;
1319
+ mesh: z.ZodString;
1320
+ count: z.ZodNumber;
1321
+ origin_vx: z.ZodOptional<z.ZodNumber>;
1322
+ origin_vy: z.ZodOptional<z.ZodNumber>;
1323
+ origin_vz: z.ZodOptional<z.ZodNumber>;
1324
+ origin_x: z.ZodOptional<z.ZodNumber>;
1325
+ origin_y: z.ZodOptional<z.ZodNumber>;
1326
+ origin_z: z.ZodOptional<z.ZodNumber>;
1327
+ }, z.core.$strip>;
1328
+ columns: {
1329
+ azimuth_bin: {
1330
+ description: string;
1331
+ unit: "index";
1332
+ };
1333
+ elevation_bin: {
1334
+ description: string;
1335
+ unit: "index";
1336
+ };
1337
+ mesh: {
1338
+ description: string;
1339
+ unit: "label";
1340
+ label: true;
1341
+ };
1342
+ count: {
1343
+ description: string;
1344
+ unit: "count";
1345
+ measure: true;
1346
+ };
1347
+ origin_vx: {
1348
+ description: string;
1349
+ unit: "index";
1350
+ };
1351
+ origin_vy: {
1352
+ description: string;
1353
+ unit: "index";
1354
+ };
1355
+ origin_vz: {
1356
+ description: string;
1357
+ unit: "index";
1358
+ };
1359
+ origin_x: {
1360
+ description: string;
1361
+ unit: "world-units";
1362
+ };
1363
+ origin_y: {
1364
+ description: string;
1365
+ unit: "world-units";
1366
+ };
1367
+ origin_z: {
1368
+ description: string;
1369
+ unit: "world-units";
1370
+ };
1371
+ };
1372
+ limits: {
1373
+ maxRows: number;
1374
+ maxSummaryRows: number;
1375
+ };
1376
+ interpretation: string;
1377
+ caveats: string[];
1378
+ sourceChannels: ("camera_sample" | "pointer_click")[];
1379
+ related: ("camera_heatmap" | "click_rays" | "top_meshes")[];
1380
+ comparable: {
1381
+ primary: string;
1382
+ direction: "neutral";
1383
+ minSample: number;
1384
+ };
1385
+ category: "interaction";
1386
+ };
1387
+ top_meshes: {
1388
+ id: "top_meshes";
1389
+ title: string;
1390
+ description: string;
1391
+ builder: "buildTopMeshes";
1392
+ endpoint: {
1393
+ method: "GET";
1394
+ path: string;
1395
+ };
1396
+ grain: "mesh";
1397
+ dimensions: ("session" | "mesh")[];
1398
+ filters: ("session" | "since" | "until" | "bins" | "limit" | "format")[];
1399
+ row: z.ZodObject<{
1400
+ mesh: z.ZodString;
1401
+ count: z.ZodNumber;
1402
+ }, z.core.$strip>;
1403
+ columns: {
1404
+ mesh: {
1405
+ description: string;
1406
+ unit: "label";
1407
+ label: true;
1408
+ };
1409
+ count: {
1410
+ description: string;
1411
+ unit: "count";
1412
+ measure: true;
1413
+ };
1414
+ };
1415
+ limits: {
1416
+ maxRows: number;
1417
+ maxSummaryRows: number;
1418
+ };
1419
+ interpretation: string;
1420
+ caveats: string[];
1421
+ sourceChannels: ("camera_sample" | "pointer_click" | "mesh_interaction")[];
1422
+ related: ("mesh_sources" | "mesh_dwell" | "mesh_blind_spots" | "mesh_interaction_kinds")[];
1423
+ comparable: {
1424
+ primary: string;
1425
+ direction: "neutral";
1426
+ minSample: number;
1427
+ };
1428
+ category: "interaction";
1429
+ };
1430
+ mesh_sources: {
1431
+ id: "mesh_sources";
1432
+ title: string;
1433
+ description: string;
1434
+ builder: "buildTopMeshesBySource";
1435
+ endpoint: {
1436
+ method: "GET";
1437
+ path: string;
1438
+ };
1439
+ grain: "mesh";
1440
+ dimensions: ("scene" | "session" | "mesh" | "source" | "cameraMode")[];
1441
+ filters: ("scene" | "session" | "source" | "cameraMode" | "since" | "until" | "bins" | "limit" | "format")[];
1442
+ row: z.ZodObject<{
1443
+ mesh: z.ZodString;
1444
+ source: z.ZodString;
1445
+ count: z.ZodNumber;
1446
+ }, z.core.$strip>;
1447
+ columns: {
1448
+ mesh: {
1449
+ description: string;
1450
+ unit: "label";
1451
+ label: true;
1452
+ };
1453
+ source: {
1454
+ description: string;
1455
+ unit: "label";
1456
+ };
1457
+ count: {
1458
+ description: string;
1459
+ unit: "count";
1460
+ measure: true;
1461
+ };
1462
+ };
1463
+ limits: {
1464
+ maxRows: number;
1465
+ maxSummaryRows: number;
1466
+ };
1467
+ interpretation: string;
1468
+ caveats: string[];
1469
+ sourceChannels: ("pointer_click" | "mesh_interaction")[];
1470
+ related: ("top_meshes" | "mesh_interaction_kinds" | "interaction_sources")[];
1471
+ comparable: {
1472
+ primary: string;
1473
+ direction: "neutral";
1474
+ minSample: number;
1475
+ };
1476
+ category: "interaction";
1477
+ };
1478
+ mesh_trend: {
1479
+ id: "mesh_trend";
1480
+ title: string;
1481
+ description: string;
1482
+ builder: "buildTopMeshesTrend";
1483
+ endpoint: {
1484
+ method: "GET";
1485
+ path: string;
1486
+ };
1487
+ grain: "bucket";
1488
+ dimensions: ("scene" | "session" | "mesh" | "source" | "cameraMode")[];
1489
+ filters: ("scene" | "session" | "source" | "cameraMode" | "since" | "until" | "bins" | "limit" | "interval" | "format")[];
1490
+ row: z.ZodObject<{
1491
+ mesh: z.ZodString;
1492
+ bucket: z.ZodNumber;
1493
+ count: z.ZodNumber;
1494
+ }, z.core.$strip>;
1495
+ columns: {
1496
+ mesh: {
1497
+ description: string;
1498
+ unit: "label";
1499
+ label: true;
1500
+ };
1501
+ bucket: {
1502
+ description: string;
1503
+ unit: "epoch-ms";
1504
+ axis: true;
1505
+ };
1506
+ count: {
1507
+ description: string;
1508
+ unit: "count";
1509
+ measure: true;
1510
+ };
1511
+ };
1512
+ limits: {
1513
+ maxRows: number;
1514
+ maxSummaryRows: number;
1515
+ };
1516
+ interpretation: string;
1517
+ caveats: string[];
1518
+ sourceChannels: ("pointer_click" | "mesh_interaction")[];
1519
+ related: ("top_meshes" | "timeseries" | "mesh_sources")[];
1520
+ comparable: {
1521
+ primary: string;
1522
+ direction: "neutral";
1523
+ minSample: number;
1524
+ };
1525
+ category: "interaction";
1526
+ };
1527
+ mesh_dwell: {
1528
+ id: "mesh_dwell";
1529
+ title: string;
1530
+ description: string;
1531
+ builder: "buildMeshDwell";
1532
+ endpoint: {
1533
+ method: "GET";
1534
+ path: string;
1535
+ };
1536
+ grain: "mesh";
1537
+ dimensions: ("scene" | "session" | "mesh")[];
1538
+ filters: ("scene" | "session" | "since" | "until" | "bins" | "limit" | "format")[];
1539
+ row: z.ZodObject<{
1540
+ mesh: z.ZodString;
1541
+ visible_ms: z.ZodNumber;
1542
+ centered_ms: z.ZodNumber;
1543
+ max_screen_fraction: z.ZodNumber;
1544
+ samples: z.ZodNumber;
1545
+ }, z.core.$strip>;
1546
+ columns: {
1547
+ mesh: {
1548
+ description: string;
1549
+ unit: "label";
1550
+ label: true;
1551
+ };
1552
+ visible_ms: {
1553
+ description: string;
1554
+ unit: "ms";
1555
+ measure: true;
1556
+ };
1557
+ centered_ms: {
1558
+ description: string;
1559
+ unit: "ms";
1560
+ };
1561
+ max_screen_fraction: {
1562
+ description: string;
1563
+ unit: "ratio";
1564
+ };
1565
+ samples: {
1566
+ description: string;
1567
+ unit: "count";
1568
+ };
1569
+ };
1570
+ limits: {
1571
+ maxRows: number;
1572
+ maxSummaryRows: number;
1573
+ };
1574
+ interpretation: string;
1575
+ caveats: string[];
1576
+ sourceChannels: "mesh_visibility"[];
1577
+ related: ("top_meshes" | "gaze_heatmap" | "mesh_blind_spots" | "hover_dwell")[];
1578
+ comparable: {
1579
+ primary: string;
1580
+ direction: "neutral";
1581
+ minSample: number;
1582
+ };
1583
+ category: "attention";
1584
+ };
1585
+ mesh_blind_spots: {
1586
+ id: "mesh_blind_spots";
1587
+ title: string;
1588
+ description: string;
1589
+ builder: "buildMeshBlindSpots";
1590
+ endpoint: {
1591
+ method: "GET";
1592
+ path: string;
1593
+ };
1594
+ grain: "mesh";
1595
+ dimensions: ("scene" | "session" | "mesh")[];
1596
+ filters: ("scene" | "session" | "since" | "until" | "bins" | "limit" | "format")[];
1597
+ row: z.ZodObject<{
1598
+ mesh: z.ZodString;
1599
+ visible_ms: z.ZodNumber;
1600
+ vis_samples: z.ZodNumber;
1601
+ interactions: z.ZodNumber;
1602
+ hover_ms: z.ZodNumber;
1603
+ hover_episodes: z.ZodNumber;
1604
+ }, z.core.$strip>;
1605
+ columns: {
1606
+ mesh: {
1607
+ description: string;
1608
+ unit: "label";
1609
+ label: true;
1610
+ };
1611
+ visible_ms: {
1612
+ description: string;
1613
+ unit: "ms";
1614
+ measure: true;
1615
+ };
1616
+ vis_samples: {
1617
+ description: string;
1618
+ unit: "count";
1619
+ };
1620
+ interactions: {
1621
+ description: string;
1622
+ unit: "count";
1623
+ };
1624
+ hover_ms: {
1625
+ description: string;
1626
+ unit: "ms";
1627
+ };
1628
+ hover_episodes: {
1629
+ description: string;
1630
+ unit: "count";
1631
+ };
1632
+ };
1633
+ limits: {
1634
+ maxRows: number;
1635
+ maxSummaryRows: number;
1636
+ };
1637
+ interpretation: string;
1638
+ caveats: string[];
1639
+ sourceChannels: ("hover_dwell" | "mesh_interaction" | "mesh_visibility")[];
1640
+ related: ("top_meshes" | "gaze_heatmap" | "mesh_dwell" | "hover_dwell")[];
1641
+ comparable: {
1642
+ primary: string;
1643
+ direction: "up";
1644
+ minSample: number;
1645
+ };
1646
+ category: "attention";
1647
+ };
1648
+ mesh_interaction_kinds: {
1649
+ id: "mesh_interaction_kinds";
1650
+ title: string;
1651
+ description: string;
1652
+ builder: "buildMeshInteractionKinds";
1653
+ endpoint: {
1654
+ method: "GET";
1655
+ path: string;
1656
+ };
1657
+ grain: "mesh";
1658
+ dimensions: ("scene" | "session" | "mesh" | "name" | "source" | "cameraMode")[];
1659
+ filters: ("scene" | "session" | "source" | "cameraMode" | "since" | "until" | "bins" | "limit" | "format")[];
1660
+ row: z.ZodObject<{
1661
+ mesh: z.ZodString;
1662
+ kind: z.ZodString;
1663
+ count: z.ZodNumber;
1664
+ }, z.core.$strip>;
1665
+ columns: {
1666
+ mesh: {
1667
+ description: string;
1668
+ unit: "label";
1669
+ label: true;
1670
+ };
1671
+ kind: {
1672
+ description: string;
1673
+ unit: "label";
1674
+ };
1675
+ count: {
1676
+ description: string;
1677
+ unit: "count";
1678
+ measure: true;
1679
+ };
1680
+ };
1681
+ limits: {
1682
+ maxRows: number;
1683
+ maxSummaryRows: number;
1684
+ };
1685
+ interpretation: string;
1686
+ caveats: string[];
1687
+ sourceChannels: "mesh_interaction"[];
1688
+ related: ("top_meshes" | "mesh_sources" | "hover_dwell")[];
1689
+ comparable: {
1690
+ primary: string;
1691
+ direction: "neutral";
1692
+ minSample: number;
1693
+ };
1694
+ category: "interaction";
1695
+ };
1696
+ mesh_reachability: {
1697
+ id: "mesh_reachability";
1698
+ title: string;
1699
+ description: string;
1700
+ builder: "buildReachability";
1701
+ endpoint: {
1702
+ method: "GET";
1703
+ path: string;
1704
+ };
1705
+ grain: "mesh";
1706
+ dimensions: ("scene" | "session" | "mesh" | "source" | "cameraMode")[];
1707
+ filters: ("scene" | "session" | "source" | "cameraMode" | "since" | "until" | "bins" | "limit" | "bucketSize" | "format")[];
1708
+ row: z.ZodObject<{
1709
+ mesh: z.ZodString;
1710
+ bucket: z.ZodNumber;
1711
+ count: z.ZodNumber;
1712
+ avg_distance: z.ZodNumber;
1713
+ }, z.core.$strip>;
1714
+ columns: {
1715
+ mesh: {
1716
+ description: string;
1717
+ unit: "label";
1718
+ label: true;
1719
+ };
1720
+ bucket: {
1721
+ description: string;
1722
+ unit: "index";
1723
+ };
1724
+ count: {
1725
+ description: string;
1726
+ unit: "count";
1727
+ measure: true;
1728
+ };
1729
+ avg_distance: {
1730
+ description: string;
1731
+ unit: "world-units";
1732
+ };
1733
+ };
1734
+ limits: {
1735
+ maxRows: number;
1736
+ maxSummaryRows: number;
1737
+ };
1738
+ interpretation: string;
1739
+ caveats: string[];
1740
+ sourceChannels: ("camera_sample" | "mesh_interaction")[];
1741
+ related: ("click_rays" | "top_meshes" | "xr_sources")[];
1742
+ comparable: {
1743
+ primary: string;
1744
+ direction: "down";
1745
+ minSample: number;
1746
+ };
1747
+ category: "interaction";
1748
+ };
1749
+ dead_clicks: {
1750
+ id: "dead_clicks";
1751
+ title: string;
1752
+ description: string;
1753
+ builder: "buildDeadClicks";
1754
+ endpoint: {
1755
+ method: "GET";
1756
+ path: string;
1757
+ };
1758
+ grain: "project";
1759
+ dimensions: ("scene" | "session" | "source" | "cameraMode")[];
1760
+ filters: ("scene" | "session" | "source" | "cameraMode" | "since" | "until" | "bins" | "limit" | "format")[];
1761
+ row: z.ZodObject<{
1762
+ total_clicks: z.ZodNumber;
1763
+ dead_clicks: z.ZodNullable<z.ZodNumber>;
1764
+ }, z.core.$strip>;
1765
+ columns: {
1766
+ total_clicks: {
1767
+ description: string;
1768
+ unit: "count";
1769
+ };
1770
+ dead_clicks: {
1771
+ description: string;
1772
+ unit: "count";
1773
+ measure: true;
1774
+ rateOf: string;
1775
+ };
1776
+ };
1777
+ limits: {
1778
+ maxRows: number;
1779
+ maxSummaryRows: number;
1780
+ };
1781
+ interpretation: string;
1782
+ caveats: string[];
1783
+ sourceChannels: "pointer_click"[];
1784
+ related: ("pointer_heatmap" | "top_meshes" | "rage_clicks" | "hover_dwell")[];
1785
+ comparable: {
1786
+ primary: string;
1787
+ direction: "down";
1788
+ minSample: number;
1789
+ };
1790
+ category: "interaction";
1791
+ };
1792
+ rage_clicks: {
1793
+ id: "rage_clicks";
1794
+ title: string;
1795
+ description: string;
1796
+ builder: "buildRageClicks";
1797
+ endpoint: {
1798
+ method: "GET";
1799
+ path: string;
1800
+ };
1801
+ grain: "row";
1802
+ dimensions: ("scene" | "session" | "mesh" | "source" | "cameraMode")[];
1803
+ filters: ("scene" | "session" | "source" | "cameraMode" | "since" | "until" | "bins" | "limit" | "interval" | "minRepeats" | "format")[];
1804
+ row: z.ZodObject<{
1805
+ session_id: z.ZodString;
1806
+ mesh: z.ZodString;
1807
+ bucket: z.ZodNumber;
1808
+ clicks: z.ZodNumber;
1809
+ }, z.core.$strip>;
1810
+ columns: {
1811
+ session_id: {
1812
+ description: string;
1813
+ unit: "id";
1814
+ };
1815
+ mesh: {
1816
+ description: string;
1817
+ unit: "label";
1818
+ label: true;
1819
+ };
1820
+ bucket: {
1821
+ description: string;
1822
+ unit: "epoch-ms";
1823
+ };
1824
+ clicks: {
1825
+ description: string;
1826
+ unit: "count";
1827
+ measure: true;
1828
+ };
1829
+ };
1830
+ limits: {
1831
+ maxRows: number;
1832
+ maxSummaryRows: number;
1833
+ };
1834
+ interpretation: string;
1835
+ caveats: string[];
1836
+ sourceChannels: "pointer_click"[];
1837
+ related: ("mesh_interaction_kinds" | "dead_clicks" | "hover_dwell")[];
1838
+ comparable: {
1839
+ primary: string;
1840
+ direction: "down";
1841
+ minSample: number;
1842
+ };
1843
+ category: "interaction";
1844
+ };
1845
+ hover_dwell: {
1846
+ id: "hover_dwell";
1847
+ title: string;
1848
+ description: string;
1849
+ builder: "buildHoverDwell";
1850
+ endpoint: {
1851
+ method: "GET";
1852
+ path: string;
1853
+ };
1854
+ grain: "mesh";
1855
+ dimensions: ("scene" | "session" | "mesh" | "source" | "cameraMode")[];
1856
+ filters: ("scene" | "session" | "source" | "cameraMode" | "since" | "until" | "bins" | "limit" | "format")[];
1857
+ row: z.ZodObject<{
1858
+ mesh: z.ZodString;
1859
+ dwell_ms: z.ZodNumber;
1860
+ max_dwell_ms: z.ZodNumber;
1861
+ episodes: z.ZodNumber;
1862
+ }, z.core.$strip>;
1863
+ columns: {
1864
+ mesh: {
1865
+ description: string;
1866
+ unit: "label";
1867
+ label: true;
1868
+ };
1869
+ dwell_ms: {
1870
+ description: string;
1871
+ unit: "ms";
1872
+ measure: true;
1873
+ };
1874
+ max_dwell_ms: {
1875
+ description: string;
1876
+ unit: "ms";
1877
+ };
1878
+ episodes: {
1879
+ description: string;
1880
+ unit: "count";
1881
+ };
1882
+ };
1883
+ limits: {
1884
+ maxRows: number;
1885
+ maxSummaryRows: number;
1886
+ };
1887
+ interpretation: string;
1888
+ caveats: string[];
1889
+ sourceChannels: "hover_dwell"[];
1890
+ related: ("mesh_dwell" | "mesh_blind_spots" | "mesh_interaction_kinds" | "dead_clicks")[];
1891
+ comparable: {
1892
+ primary: string;
1893
+ direction: "down";
1894
+ minSample: number;
1895
+ };
1896
+ category: "attention";
1897
+ };
1898
+ interaction_sources: {
1899
+ id: "interaction_sources";
1900
+ title: string;
1901
+ description: string;
1902
+ builder: "buildInteractionsBySource";
1903
+ endpoint: {
1904
+ method: "GET";
1905
+ path: string;
1906
+ };
1907
+ grain: "row";
1908
+ dimensions: ("scene" | "session" | "source" | "event_type" | "cameraMode")[];
1909
+ filters: ("scene" | "session" | "source" | "cameraMode" | "since" | "until" | "bins" | "limit" | "format")[];
1910
+ row: z.ZodObject<{
1911
+ event_type: z.ZodString;
1912
+ source: z.ZodString;
1913
+ count: z.ZodNumber;
1914
+ sessions: z.ZodNumber;
1915
+ }, z.core.$strip>;
1916
+ columns: {
1917
+ event_type: {
1918
+ description: string;
1919
+ unit: "label";
1920
+ };
1921
+ source: {
1922
+ description: string;
1923
+ unit: "label";
1924
+ label: true;
1925
+ };
1926
+ count: {
1927
+ description: string;
1928
+ unit: "count";
1929
+ measure: true;
1930
+ };
1931
+ sessions: {
1932
+ description: string;
1933
+ unit: "sessions";
1934
+ };
1935
+ };
1936
+ limits: {
1937
+ maxRows: number;
1938
+ maxSummaryRows: number;
1939
+ };
1940
+ interpretation: string;
1941
+ caveats: string[];
1942
+ sourceChannels: ("pointer_move" | "pointer_click" | "mesh_interaction" | "input_action")[];
1943
+ related: ("xr_sources" | "mesh_sources" | "top_input_actions")[];
1944
+ comparable: {
1945
+ primary: string;
1946
+ direction: "neutral";
1947
+ minSample: number;
1948
+ };
1949
+ category: "interaction";
1950
+ };
1951
+ top_input_actions: {
1952
+ id: "top_input_actions";
1953
+ title: string;
1954
+ description: string;
1955
+ builder: "buildTopInputActions";
1956
+ endpoint: {
1957
+ method: "GET";
1958
+ path: string;
1959
+ };
1960
+ grain: "row";
1961
+ dimensions: ("scene" | "session" | "name" | "source" | "cameraMode")[];
1962
+ filters: ("scene" | "session" | "source" | "cameraMode" | "since" | "until" | "bins" | "limit" | "format")[];
1963
+ row: z.ZodObject<{
1964
+ action: z.ZodString;
1965
+ source: z.ZodString;
1966
+ count: z.ZodNumber;
1967
+ }, z.core.$strip>;
1968
+ columns: {
1969
+ action: {
1970
+ description: string;
1971
+ unit: "label";
1972
+ label: true;
1973
+ };
1974
+ source: {
1975
+ description: string;
1976
+ unit: "label";
1977
+ };
1978
+ count: {
1979
+ description: string;
1980
+ unit: "count";
1981
+ measure: true;
1982
+ };
1983
+ };
1984
+ limits: {
1985
+ maxRows: number;
1986
+ maxSummaryRows: number;
1987
+ };
1988
+ interpretation: string;
1989
+ caveats: string[];
1990
+ sourceChannels: "input_action"[];
1991
+ related: ("interaction_sources" | "camera_gestures")[];
1992
+ comparable: {
1993
+ primary: string;
1994
+ direction: "neutral";
1995
+ minSample: number;
1996
+ };
1997
+ category: "interaction";
1998
+ };
1999
+ camera_gestures: {
2000
+ id: "camera_gestures";
2001
+ title: string;
2002
+ description: string;
2003
+ builder: "buildCameraGestures";
2004
+ endpoint: {
2005
+ method: "GET";
2006
+ path: string;
2007
+ };
2008
+ grain: "row";
2009
+ dimensions: ("scene" | "session" | "name" | "source" | "cameraMode")[];
2010
+ filters: ("scene" | "session" | "source" | "cameraMode" | "since" | "until" | "bins" | "limit" | "format")[];
2011
+ row: z.ZodObject<{
2012
+ kind: z.ZodString;
2013
+ gestures: z.ZodNumber;
2014
+ total_ms: z.ZodNumber;
2015
+ avg_ms: z.ZodNumber;
2016
+ max_ms: z.ZodNumber;
2017
+ }, z.core.$strip>;
2018
+ columns: {
2019
+ kind: {
2020
+ description: string;
2021
+ unit: "label";
2022
+ label: true;
2023
+ };
2024
+ gestures: {
2025
+ description: string;
2026
+ unit: "count";
2027
+ measure: true;
2028
+ };
2029
+ total_ms: {
2030
+ description: string;
2031
+ unit: "ms";
2032
+ };
2033
+ avg_ms: {
2034
+ description: string;
2035
+ unit: "ms";
2036
+ };
2037
+ max_ms: {
2038
+ description: string;
2039
+ unit: "ms";
2040
+ };
2041
+ };
2042
+ limits: {
2043
+ maxRows: number;
2044
+ maxSummaryRows: number;
2045
+ };
2046
+ interpretation: string;
2047
+ caveats: string[];
2048
+ sourceChannels: "camera_gesture"[];
2049
+ related: ("xr_locomotion" | "camera_distance" | "top_input_actions" | "navigation_stats")[];
2050
+ comparable: {
2051
+ primary: string;
2052
+ direction: "neutral";
2053
+ minSample: number;
2054
+ };
2055
+ category: "navigation";
2056
+ };
2057
+ navigation_stats: {
2058
+ id: "navigation_stats";
2059
+ title: string;
2060
+ description: string;
2061
+ builder: "buildNavigationStats";
2062
+ endpoint: {
2063
+ method: "GET";
2064
+ path: string;
2065
+ };
2066
+ grain: "session";
2067
+ dimensions: ("scene" | "session")[];
2068
+ filters: ("scene" | "session" | "since" | "until" | "limit" | "moveThreshold" | "format")[];
2069
+ row: z.ZodObject<{
2070
+ session_id: z.ZodString;
2071
+ segments: z.ZodNumber;
2072
+ total_distance: z.ZodNumber;
2073
+ active_segments: z.ZodNumber;
2074
+ active_distance: z.ZodNumber;
2075
+ }, z.core.$strip>;
2076
+ columns: {
2077
+ session_id: {
2078
+ description: string;
2079
+ unit: "id";
2080
+ label: true;
2081
+ };
2082
+ segments: {
2083
+ description: string;
2084
+ unit: "count";
2085
+ };
2086
+ total_distance: {
2087
+ description: string;
2088
+ unit: "world-units";
2089
+ measure: true;
2090
+ };
2091
+ active_segments: {
2092
+ description: string;
2093
+ unit: "count";
2094
+ rateOf: string;
2095
+ };
2096
+ active_distance: {
2097
+ description: string;
2098
+ unit: "world-units";
2099
+ };
2100
+ };
2101
+ limits: {
2102
+ maxRows: number;
2103
+ maxSummaryRows: number;
2104
+ };
2105
+ interpretation: string;
2106
+ caveats: string[];
2107
+ sourceChannels: "camera_sample"[];
2108
+ related: ("aggregate_paths" | "position_heatmap" | "camera_gestures" | "backtrack_ratio")[];
2109
+ comparable: {
2110
+ primary: string;
2111
+ direction: "neutral";
2112
+ minSample: number;
2113
+ };
2114
+ category: "navigation";
2115
+ };
2116
+ backtrack_ratio: {
2117
+ id: "backtrack_ratio";
2118
+ title: string;
2119
+ description: string;
2120
+ builder: "buildBacktrackRatio";
2121
+ endpoint: {
2122
+ method: "GET";
2123
+ path: string;
2124
+ };
2125
+ grain: "scene";
2126
+ dimensions: ("scene" | "session")[];
2127
+ filters: ("scene" | "session" | "since" | "until" | "limit" | "cellSize" | "format")[];
2128
+ row: z.ZodObject<{
2129
+ scene: z.ZodString;
2130
+ sessions: z.ZodNumber;
2131
+ entries: z.ZodNumber;
2132
+ revisits: z.ZodNumber;
2133
+ backtrack_ratio: z.ZodNumber;
2134
+ }, z.core.$strip>;
2135
+ columns: {
2136
+ scene: {
2137
+ description: string;
2138
+ unit: "id";
2139
+ label: true;
2140
+ };
2141
+ sessions: {
2142
+ description: string;
2143
+ unit: "sessions";
2144
+ };
2145
+ entries: {
2146
+ description: string;
2147
+ unit: "count";
2148
+ };
2149
+ revisits: {
2150
+ description: string;
2151
+ unit: "count";
2152
+ rateOf: string;
2153
+ };
2154
+ backtrack_ratio: {
2155
+ description: string;
2156
+ unit: "ratio";
2157
+ measure: true;
2158
+ };
2159
+ };
2160
+ limits: {
2161
+ maxRows: number;
2162
+ maxSummaryRows: number;
2163
+ };
2164
+ interpretation: string;
2165
+ caveats: string[];
2166
+ sourceChannels: "camera_sample"[];
2167
+ related: ("aggregate_paths" | "position_heatmap" | "navigation_stats")[];
2168
+ comparable: {
2169
+ primary: string;
2170
+ direction: "down";
2171
+ minSample: number;
2172
+ };
2173
+ category: "navigation";
2174
+ };
2175
+ perf_summary: {
2176
+ id: "perf_summary";
2177
+ title: string;
2178
+ description: string;
2179
+ builder: "buildPerfSummary";
2180
+ endpoint: {
2181
+ method: "GET";
2182
+ path: string;
2183
+ };
2184
+ grain: "project";
2185
+ dimensions: "session"[];
2186
+ filters: ("session" | "since" | "until" | "bins" | "limit" | "format")[];
2187
+ row: z.ZodObject<{
2188
+ samples: z.ZodNumber;
2189
+ avg_fps: z.ZodNullable<z.ZodNumber>;
2190
+ min_fps: z.ZodNullable<z.ZodNumber>;
2191
+ p50_fps: z.ZodNullable<z.ZodNumber>;
2192
+ }, z.core.$strip>;
2193
+ columns: {
2194
+ samples: {
2195
+ description: string;
2196
+ unit: "count";
2197
+ };
2198
+ avg_fps: {
2199
+ description: string;
2200
+ unit: "fps";
2201
+ measure: true;
2202
+ };
2203
+ min_fps: {
2204
+ description: string;
2205
+ unit: "fps";
2206
+ };
2207
+ p50_fps: {
2208
+ description: string;
2209
+ unit: "fps";
2210
+ };
2211
+ };
2212
+ limits: {
2213
+ maxRows: number;
2214
+ maxSummaryRows: number;
2215
+ };
2216
+ interpretation: string;
2217
+ caveats: string[];
2218
+ sourceChannels: "frame_perf"[];
2219
+ related: ("render_scale_truth" | "perf_distribution" | "jank_rate" | "perf_by_scene")[];
2220
+ comparable: {
2221
+ primary: string;
2222
+ direction: "up";
2223
+ minSample: number;
2224
+ };
2225
+ category: "performance";
2226
+ };
2227
+ render_scale_truth: {
2228
+ id: "render_scale_truth";
2229
+ title: string;
2230
+ description: string;
2231
+ builder: "buildRenderScaleTruth";
2232
+ endpoint: {
2233
+ method: "GET";
2234
+ path: string;
2235
+ };
2236
+ grain: "project";
2237
+ dimensions: "session"[];
2238
+ filters: ("session" | "since" | "until" | "bins" | "limit" | "format")[];
2239
+ row: z.ZodObject<{
2240
+ samples: z.ZodNumber;
2241
+ avg_fps: z.ZodNullable<z.ZodNumber>;
2242
+ p50_fps: z.ZodNullable<z.ZodNumber>;
2243
+ avg_render_scale: z.ZodNullable<z.ZodNumber>;
2244
+ p50_render_scale: z.ZodNullable<z.ZodNumber>;
2245
+ downscaled_samples: z.ZodNullable<z.ZodNumber>;
2246
+ scale_samples: z.ZodNullable<z.ZodNumber>;
2247
+ }, z.core.$strip>;
2248
+ columns: {
2249
+ samples: {
2250
+ description: string;
2251
+ unit: "count";
2252
+ };
2253
+ avg_fps: {
2254
+ description: string;
2255
+ unit: "fps";
2256
+ };
2257
+ p50_fps: {
2258
+ description: string;
2259
+ unit: "fps";
2260
+ measure: true;
2261
+ };
2262
+ avg_render_scale: {
2263
+ description: string;
2264
+ unit: "ratio";
2265
+ };
2266
+ p50_render_scale: {
2267
+ description: string;
2268
+ unit: "ratio";
2269
+ };
2270
+ downscaled_samples: {
2271
+ description: string;
2272
+ unit: "count";
2273
+ rateOf: string;
2274
+ };
2275
+ scale_samples: {
2276
+ description: string;
2277
+ unit: "count";
2278
+ };
2279
+ };
2280
+ limits: {
2281
+ maxRows: number;
2282
+ maxSummaryRows: number;
2283
+ };
2284
+ interpretation: string;
2285
+ caveats: string[];
2286
+ sourceChannels: "frame_perf"[];
2287
+ related: ("perf_summary" | "perf_distribution" | "capability_changes")[];
2288
+ comparable: {
2289
+ primary: string;
2290
+ direction: "up";
2291
+ minSample: number;
2292
+ };
2293
+ category: "performance";
2294
+ };
2295
+ perf_distribution: {
2296
+ id: "perf_distribution";
2297
+ title: string;
2298
+ description: string;
2299
+ builder: "buildPerfDistribution";
2300
+ endpoint: {
2301
+ method: "GET";
2302
+ path: string;
2303
+ };
2304
+ grain: "project";
2305
+ dimensions: ("scene" | "session")[];
2306
+ filters: ("scene" | "session" | "since" | "until" | "bins" | "limit" | "format")[];
2307
+ row: z.ZodObject<{
2308
+ sessions: z.ZodNumber;
2309
+ samples: z.ZodNullable<z.ZodNumber>;
2310
+ p05_fps: z.ZodNullable<z.ZodNumber>;
2311
+ p50_fps: z.ZodNullable<z.ZodNumber>;
2312
+ p95_fps: z.ZodNullable<z.ZodNumber>;
2313
+ }, z.core.$strip>;
2314
+ columns: {
2315
+ sessions: {
2316
+ description: string;
2317
+ unit: "sessions";
2318
+ };
2319
+ samples: {
2320
+ description: string;
2321
+ unit: "count";
2322
+ };
2323
+ p05_fps: {
2324
+ description: string;
2325
+ unit: "fps";
2326
+ };
2327
+ p50_fps: {
2328
+ description: string;
2329
+ unit: "fps";
2330
+ measure: true;
2331
+ };
2332
+ p95_fps: {
2333
+ description: string;
2334
+ unit: "fps";
2335
+ };
2336
+ };
2337
+ limits: {
2338
+ maxRows: number;
2339
+ maxSummaryRows: number;
2340
+ };
2341
+ interpretation: string;
2342
+ caveats: string[];
2343
+ sourceChannels: "frame_perf"[];
2344
+ related: ("perf_summary" | "fps_histogram" | "frame_time_percentiles" | "jank_rate")[];
2345
+ comparable: {
2346
+ primary: string;
2347
+ direction: "up";
2348
+ minSample: number;
2349
+ };
2350
+ category: "performance";
2351
+ };
2352
+ fps_histogram: {
2353
+ id: "fps_histogram";
2354
+ title: string;
2355
+ description: string;
2356
+ builder: "buildFpsHistogram";
2357
+ endpoint: {
2358
+ method: "GET";
2359
+ path: string;
2360
+ };
2361
+ grain: "bucket";
2362
+ dimensions: ("scene" | "session")[];
2363
+ filters: ("scene" | "session" | "since" | "until" | "bins" | "limit" | "bucket" | "format")[];
2364
+ row: z.ZodObject<{
2365
+ bucket: z.ZodNumber;
2366
+ sessions: z.ZodNumber;
2367
+ }, z.core.$strip>;
2368
+ columns: {
2369
+ bucket: {
2370
+ description: string;
2371
+ unit: "fps";
2372
+ label: true;
2373
+ axis: true;
2374
+ };
2375
+ sessions: {
2376
+ description: string;
2377
+ unit: "sessions";
2378
+ measure: true;
2379
+ };
2380
+ };
2381
+ limits: {
2382
+ maxRows: number;
2383
+ maxSummaryRows: number;
2384
+ };
2385
+ interpretation: string;
2386
+ caveats: string[];
2387
+ sourceChannels: "frame_perf"[];
2388
+ related: ("perf_distribution" | "perf_by_device" | "perf_by_scene")[];
2389
+ comparable: {
2390
+ primary: string;
2391
+ direction: "neutral";
2392
+ minSample: number;
2393
+ };
2394
+ category: "performance";
2395
+ };
2396
+ frame_time_percentiles: {
2397
+ id: "frame_time_percentiles";
2398
+ title: string;
2399
+ description: string;
2400
+ builder: "buildFrameTimePercentiles";
2401
+ endpoint: {
2402
+ method: "GET";
2403
+ path: string;
2404
+ };
2405
+ grain: "project";
2406
+ dimensions: ("scene" | "session")[];
2407
+ filters: ("scene" | "session" | "since" | "until" | "bins" | "limit" | "format")[];
2408
+ row: z.ZodObject<{
2409
+ sessions: z.ZodNumber;
2410
+ samples: z.ZodNullable<z.ZodNumber>;
2411
+ p50_ms: z.ZodNullable<z.ZodNumber>;
2412
+ p95_ms: z.ZodNullable<z.ZodNumber>;
2413
+ }, z.core.$strip>;
2414
+ columns: {
2415
+ sessions: {
2416
+ description: string;
2417
+ unit: "sessions";
2418
+ };
2419
+ samples: {
2420
+ description: string;
2421
+ unit: "count";
2422
+ };
2423
+ p50_ms: {
2424
+ description: string;
2425
+ unit: "ms";
2426
+ measure: true;
2427
+ };
2428
+ p95_ms: {
2429
+ description: string;
2430
+ unit: "ms";
2431
+ };
2432
+ };
2433
+ limits: {
2434
+ maxRows: number;
2435
+ maxSummaryRows: number;
2436
+ };
2437
+ interpretation: string;
2438
+ caveats: string[];
2439
+ sourceChannels: "frame_perf"[];
2440
+ related: ("perf_distribution" | "jank_rate" | "compile_stalls")[];
2441
+ comparable: {
2442
+ primary: string;
2443
+ direction: "down";
2444
+ minSample: number;
2445
+ };
2446
+ category: "performance";
2447
+ };
2448
+ jank_rate: {
2449
+ id: "jank_rate";
2450
+ title: string;
2451
+ description: string;
2452
+ builder: "buildJankRate";
2453
+ endpoint: {
2454
+ method: "GET";
2455
+ path: string;
2456
+ };
2457
+ grain: "project";
2458
+ dimensions: ("scene" | "session")[];
2459
+ filters: ("scene" | "session" | "since" | "until" | "bins" | "limit" | "format")[];
2460
+ row: z.ZodObject<{
2461
+ sessions: z.ZodNumber;
2462
+ total_long_frames: z.ZodNullable<z.ZodNumber>;
2463
+ median_rate: z.ZodNullable<z.ZodNumber>;
2464
+ worst_decile_rate: z.ZodNullable<z.ZodNumber>;
2465
+ }, z.core.$strip>;
2466
+ columns: {
2467
+ sessions: {
2468
+ description: string;
2469
+ unit: "sessions";
2470
+ };
2471
+ total_long_frames: {
2472
+ description: string;
2473
+ unit: "count";
2474
+ };
2475
+ median_rate: {
2476
+ description: string;
2477
+ unit: "ratio";
2478
+ measure: true;
2479
+ };
2480
+ worst_decile_rate: {
2481
+ description: string;
2482
+ unit: "ratio";
2483
+ };
2484
+ };
2485
+ limits: {
2486
+ maxRows: number;
2487
+ maxSummaryRows: number;
2488
+ };
2489
+ interpretation: string;
2490
+ caveats: string[];
2491
+ sourceChannels: "frame_perf"[];
2492
+ related: ("perf_distribution" | "frame_time_percentiles" | "perf_churn" | "perf_by_device")[];
2493
+ comparable: {
2494
+ primary: string;
2495
+ direction: "down";
2496
+ minSample: number;
2497
+ };
2498
+ category: "performance";
2499
+ };
2500
+ perf_churn: {
2501
+ id: "perf_churn";
2502
+ title: string;
2503
+ description: string;
2504
+ builder: "buildPerfChurn";
2505
+ endpoint: {
2506
+ method: "GET";
2507
+ path: string;
2508
+ };
2509
+ grain: "project";
2510
+ dimensions: ("scene" | "session")[];
2511
+ filters: ("scene" | "session" | "since" | "until" | "bins" | "limit" | "windowMs" | "fpsThreshold" | "stallMs" | "format")[];
2512
+ row: z.ZodObject<{
2513
+ sessions: z.ZodNumber;
2514
+ churn_sessions: z.ZodNumber;
2515
+ fps_churn_sessions: z.ZodNullable<z.ZodNumber>;
2516
+ stall_churn_sessions: z.ZodNullable<z.ZodNumber>;
2517
+ }, z.core.$strip>;
2518
+ columns: {
2519
+ sessions: {
2520
+ description: string;
2521
+ unit: "sessions";
2522
+ };
2523
+ churn_sessions: {
2524
+ description: string;
2525
+ unit: "sessions";
2526
+ measure: true;
2527
+ rateOf: string;
2528
+ };
2529
+ fps_churn_sessions: {
2530
+ description: string;
2531
+ unit: "sessions";
2532
+ };
2533
+ stall_churn_sessions: {
2534
+ description: string;
2535
+ unit: "sessions";
2536
+ };
2537
+ };
2538
+ limits: {
2539
+ maxRows: number;
2540
+ maxSummaryRows: number;
2541
+ };
2542
+ interpretation: string;
2543
+ caveats: string[];
2544
+ sourceChannels: ("session_end" | "frame_perf" | "compile_stall")[];
2545
+ related: ("perf_distribution" | "jank_rate" | "compile_stalls" | "load_bounce_funnel")[];
2546
+ comparable: {
2547
+ primary: string;
2548
+ direction: "down";
2549
+ minSample: number;
2550
+ };
2551
+ category: "performance";
2552
+ };
2553
+ perf_by_device: {
2554
+ id: "perf_by_device";
2555
+ title: string;
2556
+ description: string;
2557
+ builder: "buildPerfByDevice";
2558
+ endpoint: {
2559
+ method: "GET";
2560
+ path: string;
2561
+ };
2562
+ grain: "row";
2563
+ dimensions: ("scene" | "session" | "device.engine" | "device.renderer" | "device.isMobile" | "device.browser" | "device.os")[];
2564
+ filters: ("scene" | "session" | "since" | "until" | "bins" | "limit" | "format")[];
2565
+ row: z.ZodObject<{
2566
+ engine: z.ZodString;
2567
+ is_mobile: z.ZodString;
2568
+ renderer: z.ZodString;
2569
+ browser: z.ZodString;
2570
+ os: z.ZodString;
2571
+ sessions: z.ZodNumber;
2572
+ samples: z.ZodNumber;
2573
+ p50_fps: z.ZodNumber;
2574
+ }, z.core.$strip>;
2575
+ columns: {
2576
+ engine: {
2577
+ description: string;
2578
+ unit: "label";
2579
+ };
2580
+ is_mobile: {
2581
+ description: string;
2582
+ unit: "label";
2583
+ };
2584
+ renderer: {
2585
+ description: string;
2586
+ unit: "label";
2587
+ label: true;
2588
+ };
2589
+ browser: {
2590
+ description: string;
2591
+ unit: "label";
2592
+ };
2593
+ os: {
2594
+ description: string;
2595
+ unit: "label";
2596
+ };
2597
+ sessions: {
2598
+ description: string;
2599
+ unit: "sessions";
2600
+ };
2601
+ samples: {
2602
+ description: string;
2603
+ unit: "count";
2604
+ };
2605
+ p50_fps: {
2606
+ description: string;
2607
+ unit: "fps";
2608
+ measure: true;
2609
+ };
2610
+ };
2611
+ limits: {
2612
+ maxRows: number;
2613
+ maxSummaryRows: number;
2614
+ };
2615
+ interpretation: string;
2616
+ caveats: string[];
2617
+ sourceChannels: ("session_start" | "frame_perf")[];
2618
+ related: ("session_meta" | "rendering_technology" | "perf_distribution" | "fps_histogram")[];
2619
+ comparable: {
2620
+ primary: string;
2621
+ direction: "up";
2622
+ minSample: number;
2623
+ };
2624
+ category: "performance";
2625
+ };
2626
+ perf_by_scene: {
2627
+ id: "perf_by_scene";
2628
+ title: string;
2629
+ description: string;
2630
+ builder: "buildPerfByScene";
2631
+ endpoint: {
2632
+ method: "GET";
2633
+ path: string;
2634
+ };
2635
+ grain: "scene";
2636
+ dimensions: ("scene" | "session")[];
2637
+ filters: ("scene" | "session" | "since" | "until" | "bins" | "limit" | "format")[];
2638
+ row: z.ZodObject<{
2639
+ scene_id: z.ZodString;
2640
+ sessions: z.ZodNumber;
2641
+ samples: z.ZodNumber;
2642
+ p50_fps: z.ZodNumber;
2643
+ }, z.core.$strip>;
2644
+ columns: {
2645
+ scene_id: {
2646
+ description: string;
2647
+ unit: "id";
2648
+ label: true;
2649
+ };
2650
+ sessions: {
2651
+ description: string;
2652
+ unit: "sessions";
2653
+ };
2654
+ samples: {
2655
+ description: string;
2656
+ unit: "count";
2657
+ };
2658
+ p50_fps: {
2659
+ description: string;
2660
+ unit: "fps";
2661
+ measure: true;
2662
+ };
2663
+ };
2664
+ limits: {
2665
+ maxRows: number;
2666
+ maxSummaryRows: number;
2667
+ };
2668
+ interpretation: string;
2669
+ caveats: string[];
2670
+ sourceChannels: "frame_perf"[];
2671
+ related: ("list_scenes" | "perf_distribution" | "perf_by_device" | "perf_heatmap")[];
2672
+ comparable: {
2673
+ primary: string;
2674
+ direction: "up";
2675
+ minSample: number;
2676
+ };
2677
+ category: "performance";
2678
+ };
2679
+ perf_heatmap: {
2680
+ id: "perf_heatmap";
2681
+ title: string;
2682
+ description: string;
2683
+ builder: "buildPerfHeatmap";
2684
+ endpoint: {
2685
+ method: "GET";
2686
+ path: string;
2687
+ };
2688
+ grain: "voxel";
2689
+ dimensions: ("scene" | "session")[];
2690
+ filters: ("scene" | "session" | "since" | "until" | "limit" | "cellSize" | "format")[];
2691
+ row: z.ZodObject<{
2692
+ vx: z.ZodNumber;
2693
+ vy: z.ZodNumber;
2694
+ vz: z.ZodNumber;
2695
+ samples: z.ZodNumber;
2696
+ avg_fps: z.ZodNumber;
2697
+ min_fps: z.ZodNumber;
2698
+ }, z.core.$strip>;
2699
+ columns: {
2700
+ vx: {
2701
+ description: string;
2702
+ unit: "index";
2703
+ label: true;
2704
+ };
2705
+ vy: {
2706
+ description: string;
2707
+ unit: "index";
2708
+ };
2709
+ vz: {
2710
+ description: string;
2711
+ unit: "index";
2712
+ };
2713
+ samples: {
2714
+ description: string;
2715
+ unit: "count";
2716
+ };
2717
+ avg_fps: {
2718
+ description: string;
2719
+ unit: "fps";
2720
+ measure: true;
2721
+ };
2722
+ min_fps: {
2723
+ description: string;
2724
+ unit: "fps";
2725
+ };
2726
+ };
2727
+ limits: {
2728
+ maxRows: number;
2729
+ maxSummaryRows: number;
2730
+ };
2731
+ interpretation: string;
2732
+ caveats: string[];
2733
+ sourceChannels: "frame_perf"[];
2734
+ related: ("position_heatmap" | "scene_coverage" | "perf_by_scene" | "error_heatmap")[];
2735
+ comparable: {
2736
+ primary: string;
2737
+ direction: "up";
2738
+ minSample: number;
2739
+ };
2740
+ category: "performance";
2741
+ };
2742
+ perf_daily: {
2743
+ id: "perf_daily";
2744
+ title: string;
2745
+ description: string;
2746
+ builder: "buildPerfDaily";
2747
+ grain: "bucket";
2748
+ dimensions: never[];
2749
+ filters: never[];
2750
+ row: z.ZodObject<{
2751
+ day: z.ZodString;
2752
+ samples: z.ZodNumber;
2753
+ avg_fps: z.ZodNumber;
2754
+ min_fps: z.ZodNumber;
2755
+ p50_fps: z.ZodNumber;
2756
+ }, z.core.$strip>;
2757
+ columns: {
2758
+ day: {
2759
+ description: string;
2760
+ unit: "label";
2761
+ label: true;
2762
+ axis: true;
2763
+ };
2764
+ samples: {
2765
+ description: string;
2766
+ unit: "count";
2767
+ };
2768
+ avg_fps: {
2769
+ description: string;
2770
+ unit: "fps";
2771
+ measure: true;
2772
+ };
2773
+ min_fps: {
2774
+ description: string;
2775
+ unit: "fps";
2776
+ };
2777
+ p50_fps: {
2778
+ description: string;
2779
+ unit: "fps";
2780
+ };
2781
+ };
2782
+ limits: {
2783
+ maxRows: number;
2784
+ maxSummaryRows: number;
2785
+ };
2786
+ interpretation: string;
2787
+ caveats: string[];
2788
+ sourceChannels: "frame_perf"[];
2789
+ related: ("perf_summary" | "perf_distribution" | "events_daily")[];
2790
+ comparable: {
2791
+ primary: string;
2792
+ direction: "up";
2793
+ minSample: number;
2794
+ };
2795
+ category: "performance";
2796
+ };
2797
+ compile_stalls: {
2798
+ id: "compile_stalls";
2799
+ title: string;
2800
+ description: string;
2801
+ builder: "buildCompileStalls";
2802
+ endpoint: {
2803
+ method: "GET";
2804
+ path: string;
2805
+ };
2806
+ grain: "row";
2807
+ dimensions: ("scene" | "session" | "name")[];
2808
+ filters: ("scene" | "session" | "since" | "until" | "bins" | "limit" | "format")[];
2809
+ row: z.ZodObject<{
2810
+ phase: z.ZodString;
2811
+ stalls: z.ZodNumber;
2812
+ total_ms: z.ZodNumber;
2813
+ avg_ms: z.ZodNumber;
2814
+ max_ms: z.ZodNumber;
2815
+ }, z.core.$strip>;
2816
+ columns: {
2817
+ phase: {
2818
+ description: string;
2819
+ unit: "label";
2820
+ label: true;
2821
+ };
2822
+ stalls: {
2823
+ description: string;
2824
+ unit: "count";
2825
+ };
2826
+ total_ms: {
2827
+ description: string;
2828
+ unit: "ms";
2829
+ measure: true;
2830
+ };
2831
+ avg_ms: {
2832
+ description: string;
2833
+ unit: "ms";
2834
+ };
2835
+ max_ms: {
2836
+ description: string;
2837
+ unit: "ms";
2838
+ };
2839
+ };
2840
+ limits: {
2841
+ maxRows: number;
2842
+ maxSummaryRows: number;
2843
+ };
2844
+ interpretation: string;
2845
+ caveats: string[];
2846
+ sourceChannels: "compile_stall"[];
2847
+ related: ("frame_time_percentiles" | "perf_churn" | "stability_counts" | "load_bounce_funnel")[];
2848
+ comparable: {
2849
+ primary: string;
2850
+ direction: "down";
2851
+ minSample: number;
2852
+ };
2853
+ category: "performance";
2854
+ };
2855
+ resource_summary: {
2856
+ id: "resource_summary";
2857
+ title: string;
2858
+ description: string;
2859
+ builder: "buildResourceSummary";
2860
+ endpoint: {
2861
+ method: "GET";
2862
+ path: string;
2863
+ };
2864
+ grain: "project";
2865
+ dimensions: "session"[];
2866
+ filters: ("session" | "since" | "until" | "bins" | "limit" | "format")[];
2867
+ row: z.ZodObject<{
2868
+ samples: z.ZodNumber;
2869
+ avg_js_heap_bytes: z.ZodNullable<z.ZodNumber>;
2870
+ max_js_heap_bytes: z.ZodNullable<z.ZodNumber>;
2871
+ avg_triangles: z.ZodNullable<z.ZodNumber>;
2872
+ max_triangles: z.ZodNullable<z.ZodNumber>;
2873
+ avg_vertices: z.ZodNullable<z.ZodNumber>;
2874
+ max_vertices: z.ZodNullable<z.ZodNumber>;
2875
+ avg_texture_bytes: z.ZodNullable<z.ZodNumber>;
2876
+ max_texture_bytes: z.ZodNullable<z.ZodNumber>;
2877
+ avg_geometry_bytes: z.ZodNullable<z.ZodNumber>;
2878
+ max_geometry_bytes: z.ZodNullable<z.ZodNumber>;
2879
+ }, z.core.$strip>;
2880
+ columns: {
2881
+ samples: {
2882
+ description: string;
2883
+ unit: "count";
2884
+ };
2885
+ avg_js_heap_bytes: {
2886
+ description: string;
2887
+ unit: "bytes";
2888
+ measure: true;
2889
+ };
2890
+ max_js_heap_bytes: {
2891
+ description: string;
2892
+ unit: "bytes";
2893
+ };
2894
+ avg_triangles: {
2895
+ description: string;
2896
+ unit: "count";
2897
+ };
2898
+ max_triangles: {
2899
+ description: string;
2900
+ unit: "count";
2901
+ };
2902
+ avg_vertices: {
2903
+ description: string;
2904
+ unit: "count";
2905
+ };
2906
+ max_vertices: {
2907
+ description: string;
2908
+ unit: "count";
2909
+ };
2910
+ avg_texture_bytes: {
2911
+ description: string;
2912
+ unit: "bytes";
2913
+ };
2914
+ max_texture_bytes: {
2915
+ description: string;
2916
+ unit: "bytes";
2917
+ };
2918
+ avg_geometry_bytes: {
2919
+ description: string;
2920
+ unit: "bytes";
2921
+ };
2922
+ max_geometry_bytes: {
2923
+ description: string;
2924
+ unit: "bytes";
2925
+ };
2926
+ };
2927
+ limits: {
2928
+ maxRows: number;
2929
+ maxSummaryRows: number;
2930
+ };
2931
+ interpretation: string;
2932
+ caveats: string[];
2933
+ sourceChannels: "resource_sample"[];
2934
+ related: ("perf_summary" | "perf_by_device" | "resource_percentiles")[];
2935
+ comparable: {
2936
+ primary: string;
2937
+ direction: "down";
2938
+ minSample: number;
2939
+ };
2940
+ category: "performance";
2941
+ };
2942
+ resource_percentiles: {
2943
+ id: "resource_percentiles";
2944
+ title: string;
2945
+ description: string;
2946
+ builder: "buildResourcePercentiles";
2947
+ endpoint: {
2948
+ method: "GET";
2949
+ path: string;
2950
+ };
2951
+ grain: "project";
2952
+ dimensions: ("scene" | "session")[];
2953
+ filters: ("scene" | "session" | "since" | "until" | "bins" | "limit" | "format")[];
2954
+ row: z.ZodObject<{
2955
+ sessions: z.ZodNumber;
2956
+ samples: z.ZodNullable<z.ZodNumber>;
2957
+ p50_js_heap_bytes: z.ZodNullable<z.ZodNumber>;
2958
+ p95_js_heap_bytes: z.ZodNullable<z.ZodNumber>;
2959
+ p50_texture_bytes: z.ZodNullable<z.ZodNumber>;
2960
+ p95_texture_bytes: z.ZodNullable<z.ZodNumber>;
2961
+ p50_triangles: z.ZodNullable<z.ZodNumber>;
2962
+ p95_triangles: z.ZodNullable<z.ZodNumber>;
2963
+ }, z.core.$strip>;
2964
+ columns: {
2965
+ sessions: {
2966
+ description: string;
2967
+ unit: "sessions";
2968
+ };
2969
+ samples: {
2970
+ description: string;
2971
+ unit: "count";
2972
+ };
2973
+ p50_js_heap_bytes: {
2974
+ description: string;
2975
+ unit: "bytes";
2976
+ measure: true;
2977
+ };
2978
+ p95_js_heap_bytes: {
2979
+ description: string;
2980
+ unit: "bytes";
2981
+ };
2982
+ p50_texture_bytes: {
2983
+ description: string;
2984
+ unit: "bytes";
2985
+ };
2986
+ p95_texture_bytes: {
2987
+ description: string;
2988
+ unit: "bytes";
2989
+ };
2990
+ p50_triangles: {
2991
+ description: string;
2992
+ unit: "count";
2993
+ };
2994
+ p95_triangles: {
2995
+ description: string;
2996
+ unit: "count";
2997
+ };
2998
+ };
2999
+ limits: {
3000
+ maxRows: number;
3001
+ maxSummaryRows: number;
3002
+ };
3003
+ interpretation: string;
3004
+ caveats: string[];
3005
+ sourceChannels: "resource_sample"[];
3006
+ related: ("perf_distribution" | "perf_by_device" | "resource_summary")[];
3007
+ comparable: {
3008
+ primary: string;
3009
+ direction: "down";
3010
+ minSample: number;
3011
+ };
3012
+ category: "performance";
3013
+ };
3014
+ stability_counts: {
3015
+ id: "stability_counts";
3016
+ title: string;
3017
+ description: string;
3018
+ builder: "buildStabilityCounts";
3019
+ endpoint: {
3020
+ method: "GET";
3021
+ path: string;
3022
+ };
3023
+ grain: "project";
3024
+ dimensions: ("scene" | "session")[];
3025
+ filters: ("scene" | "session" | "since" | "until" | "bins" | "limit" | "format")[];
3026
+ row: z.ZodObject<{
3027
+ context_losses: z.ZodNumber;
3028
+ compile_stalls: z.ZodNumber;
3029
+ incidents: z.ZodNumber;
3030
+ }, z.core.$strip>;
3031
+ columns: {
3032
+ context_losses: {
3033
+ description: string;
3034
+ unit: "count";
3035
+ };
3036
+ compile_stalls: {
3037
+ description: string;
3038
+ unit: "count";
3039
+ };
3040
+ incidents: {
3041
+ description: string;
3042
+ unit: "count";
3043
+ measure: true;
3044
+ };
3045
+ };
3046
+ limits: {
3047
+ maxRows: number;
3048
+ maxSummaryRows: number;
3049
+ };
3050
+ interpretation: string;
3051
+ caveats: string[];
3052
+ sourceChannels: ("compile_stall" | "context_lost")[];
3053
+ related: ("event_counts" | "compile_stalls" | "graphics_diagnostics" | "capability_changes")[];
3054
+ comparable: {
3055
+ primary: string;
3056
+ direction: "down";
3057
+ minSample: number;
3058
+ };
3059
+ category: "errors";
3060
+ };
3061
+ graphics_diagnostics: {
3062
+ id: "graphics_diagnostics";
3063
+ title: string;
3064
+ description: string;
3065
+ builder: "buildGraphicsDiagnosticCounts";
3066
+ endpoint: {
3067
+ method: "GET";
3068
+ path: string;
3069
+ };
3070
+ grain: "row";
3071
+ dimensions: ("scene" | "session")[];
3072
+ filters: ("scene" | "session" | "since" | "until" | "bins" | "limit" | "format")[];
3073
+ row: z.ZodObject<{
3074
+ severity: z.ZodString;
3075
+ category: z.ZodString;
3076
+ backend: z.ZodString;
3077
+ incidents: z.ZodNumber;
3078
+ }, z.core.$strip>;
3079
+ columns: {
3080
+ severity: {
3081
+ description: string;
3082
+ unit: "label";
3083
+ };
3084
+ category: {
3085
+ description: string;
3086
+ unit: "label";
3087
+ label: true;
3088
+ };
3089
+ backend: {
3090
+ description: string;
3091
+ unit: "label";
3092
+ };
3093
+ incidents: {
3094
+ description: string;
3095
+ unit: "count";
3096
+ measure: true;
3097
+ };
3098
+ };
3099
+ limits: {
3100
+ maxRows: number;
3101
+ maxSummaryRows: number;
3102
+ };
3103
+ interpretation: string;
3104
+ caveats: string[];
3105
+ sourceChannels: "graphics_diagnostic"[];
3106
+ related: ("rendering_technology" | "stability_counts" | "error_heatmap" | "capability_changes")[];
3107
+ comparable: {
3108
+ primary: string;
3109
+ direction: "down";
3110
+ minSample: number;
3111
+ };
3112
+ category: "errors";
3113
+ };
3114
+ error_heatmap: {
3115
+ id: "error_heatmap";
3116
+ title: string;
3117
+ description: string;
3118
+ builder: "buildErrorHeatmap";
3119
+ endpoint: {
3120
+ method: "GET";
3121
+ path: string;
3122
+ };
3123
+ grain: "voxel";
3124
+ dimensions: ("scene" | "session")[];
3125
+ filters: ("scene" | "session" | "since" | "until" | "region" | "limit" | "cellSize" | "severity" | "category" | "errorKind" | "format")[];
3126
+ row: z.ZodObject<{
3127
+ vx: z.ZodNumber;
3128
+ vy: z.ZodNumber;
3129
+ vz: z.ZodNumber;
3130
+ count: z.ZodNumber;
3131
+ }, z.core.$strip>;
3132
+ columns: {
3133
+ vx: {
3134
+ description: string;
3135
+ unit: "index";
3136
+ label: true;
3137
+ };
3138
+ vy: {
3139
+ description: string;
3140
+ unit: "index";
3141
+ };
3142
+ vz: {
3143
+ description: string;
3144
+ unit: "index";
3145
+ };
3146
+ count: {
3147
+ description: string;
3148
+ unit: "count";
3149
+ measure: true;
3150
+ };
3151
+ };
3152
+ limits: {
3153
+ maxRows: number;
3154
+ maxSummaryRows: number;
3155
+ };
3156
+ interpretation: string;
3157
+ caveats: string[];
3158
+ sourceChannels: ("graphics_diagnostic" | "runtime_error")[];
3159
+ related: ("perf_heatmap" | "stability_counts" | "graphics_diagnostics")[];
3160
+ comparable: {
3161
+ primary: string;
3162
+ direction: "down";
3163
+ minSample: number;
3164
+ };
3165
+ category: "errors";
3166
+ };
3167
+ rendering_technology: {
3168
+ id: "rendering_technology";
3169
+ title: string;
3170
+ description: string;
3171
+ builder: "buildRenderingTechnology";
3172
+ endpoint: {
3173
+ method: "GET";
3174
+ path: string;
3175
+ };
3176
+ grain: "row";
3177
+ dimensions: ("scene" | "session")[];
3178
+ filters: ("scene" | "session" | "since" | "until" | "bins" | "limit" | "format")[];
3179
+ row: z.ZodObject<{
3180
+ api: z.ZodString;
3181
+ backend: z.ZodString;
3182
+ api_version: z.ZodString;
3183
+ shading_language: z.ZodString;
3184
+ sessions: z.ZodNumber;
3185
+ }, z.core.$strip>;
3186
+ columns: {
3187
+ api: {
3188
+ description: string;
3189
+ unit: "label";
3190
+ label: true;
3191
+ };
3192
+ backend: {
3193
+ description: string;
3194
+ unit: "label";
3195
+ };
3196
+ api_version: {
3197
+ description: string;
3198
+ unit: "label";
3199
+ };
3200
+ shading_language: {
3201
+ description: string;
3202
+ unit: "label";
3203
+ };
3204
+ sessions: {
3205
+ description: string;
3206
+ unit: "sessions";
3207
+ measure: true;
3208
+ };
3209
+ };
3210
+ limits: {
3211
+ maxRows: number;
3212
+ maxSummaryRows: number;
3213
+ };
3214
+ interpretation: string;
3215
+ caveats: string[];
3216
+ sourceChannels: "session_start"[];
3217
+ related: ("perf_by_device" | "graphics_diagnostics" | "capability_changes")[];
3218
+ comparable: {
3219
+ primary: string;
3220
+ direction: "neutral";
3221
+ minSample: number;
3222
+ };
3223
+ category: "performance";
3224
+ };
3225
+ capability_changes: {
3226
+ id: "capability_changes";
3227
+ title: string;
3228
+ description: string;
3229
+ builder: "buildCapabilityChanges";
3230
+ endpoint: {
3231
+ method: "GET";
3232
+ path: string;
3233
+ };
3234
+ grain: "row";
3235
+ dimensions: ("scene" | "session" | "name")[];
3236
+ filters: ("scene" | "session" | "since" | "until" | "bins" | "limit" | "format")[];
3237
+ row: z.ZodObject<{
3238
+ kind: z.ZodString;
3239
+ from: z.ZodString;
3240
+ to: z.ZodString;
3241
+ changes: z.ZodNumber;
3242
+ }, z.core.$strip>;
3243
+ columns: {
3244
+ kind: {
3245
+ description: string;
3246
+ unit: "label";
3247
+ label: true;
3248
+ };
3249
+ from: {
3250
+ description: string;
3251
+ unit: "label";
3252
+ };
3253
+ to: {
3254
+ description: string;
3255
+ unit: "label";
3256
+ };
3257
+ changes: {
3258
+ description: string;
3259
+ unit: "count";
3260
+ measure: true;
3261
+ };
3262
+ };
3263
+ limits: {
3264
+ maxRows: number;
3265
+ maxSummaryRows: number;
3266
+ };
3267
+ interpretation: string;
3268
+ caveats: string[];
3269
+ sourceChannels: "capability_change"[];
3270
+ related: ("rendering_technology" | "render_scale_truth" | "stability_counts" | "xr_tracking_quality")[];
3271
+ comparable: {
3272
+ primary: string;
3273
+ direction: "down";
3274
+ minSample: number;
3275
+ };
3276
+ category: "errors";
3277
+ };
3278
+ xr_rotation: {
3279
+ id: "xr_rotation";
3280
+ title: string;
3281
+ description: string;
3282
+ builder: "buildXrRotationRate";
3283
+ endpoint: {
3284
+ method: "GET";
3285
+ path: string;
3286
+ };
3287
+ grain: "session";
3288
+ dimensions: ("scene" | "session")[];
3289
+ filters: ("scene" | "session" | "since" | "until" | "limit" | "rapidTurn" | "format")[];
3290
+ row: z.ZodObject<{
3291
+ session_id: z.ZodString;
3292
+ samples: z.ZodNumber;
3293
+ avg_turn_rad: z.ZodNumber;
3294
+ max_turn_rad: z.ZodNumber;
3295
+ total_turn_rad: z.ZodNumber;
3296
+ rapid_segments: z.ZodNumber;
3297
+ }, z.core.$strip>;
3298
+ columns: {
3299
+ session_id: {
3300
+ description: string;
3301
+ unit: "id";
3302
+ label: true;
3303
+ };
3304
+ samples: {
3305
+ description: string;
3306
+ unit: "count";
3307
+ };
3308
+ avg_turn_rad: {
3309
+ description: string;
3310
+ unit: "radians";
3311
+ };
3312
+ max_turn_rad: {
3313
+ description: string;
3314
+ unit: "radians";
3315
+ };
3316
+ total_turn_rad: {
3317
+ description: string;
3318
+ unit: "radians";
3319
+ measure: true;
3320
+ };
3321
+ rapid_segments: {
3322
+ description: string;
3323
+ unit: "count";
3324
+ rateOf: string;
3325
+ };
3326
+ };
3327
+ limits: {
3328
+ maxRows: number;
3329
+ maxSummaryRows: number;
3330
+ };
3331
+ interpretation: string;
3332
+ caveats: string[];
3333
+ sourceChannels: "camera_sample"[];
3334
+ related: ("xr_abandonment" | "xr_locomotion" | "camera_gestures" | "xr_tracking_quality")[];
3335
+ comparable: {
3336
+ primary: string;
3337
+ direction: "down";
3338
+ minSample: number;
3339
+ };
3340
+ category: "xr";
3341
+ };
3342
+ xr_sources: {
3343
+ id: "xr_sources";
3344
+ title: string;
3345
+ description: string;
3346
+ builder: "buildXrSourceUsage";
3347
+ endpoint: {
3348
+ method: "GET";
3349
+ path: string;
3350
+ };
3351
+ grain: "row";
3352
+ dimensions: ("scene" | "session" | "source")[];
3353
+ filters: ("scene" | "session" | "since" | "until" | "bins" | "limit" | "format")[];
3354
+ row: z.ZodObject<{
3355
+ source: z.ZodString;
3356
+ interactions: z.ZodNumber;
3357
+ sessions: z.ZodNumber;
3358
+ }, z.core.$strip>;
3359
+ columns: {
3360
+ source: {
3361
+ description: string;
3362
+ unit: "label";
3363
+ label: true;
3364
+ };
3365
+ interactions: {
3366
+ description: string;
3367
+ unit: "count";
3368
+ measure: true;
3369
+ };
3370
+ sessions: {
3371
+ description: string;
3372
+ unit: "sessions";
3373
+ };
3374
+ };
3375
+ limits: {
3376
+ maxRows: number;
3377
+ maxSummaryRows: number;
3378
+ };
3379
+ interpretation: string;
3380
+ caveats: string[];
3381
+ sourceChannels: ("pointer_move" | "pointer_click" | "mesh_interaction")[];
3382
+ related: ("xr_locomotion" | "mesh_reachability" | "interaction_sources" | "xr_tracking_quality")[];
3383
+ comparable: {
3384
+ primary: string;
3385
+ direction: "neutral";
3386
+ minSample: number;
3387
+ };
3388
+ category: "xr";
3389
+ };
3390
+ xr_abandonment: {
3391
+ id: "xr_abandonment";
3392
+ title: string;
3393
+ description: string;
3394
+ builder: "buildXrAbandonment";
3395
+ endpoint: {
3396
+ method: "GET";
3397
+ path: string;
3398
+ };
3399
+ grain: "session";
3400
+ dimensions: ("scene" | "session")[];
3401
+ filters: ("scene" | "session" | "since" | "until" | "bins" | "limit" | "format")[];
3402
+ row: z.ZodObject<{
3403
+ session_id: z.ZodString;
3404
+ events: z.ZodNumber;
3405
+ xr_interactions: z.ZodNumber;
3406
+ started_at: z.ZodString;
3407
+ ended_at: z.ZodString;
3408
+ }, z.core.$strip>;
3409
+ columns: {
3410
+ session_id: {
3411
+ description: string;
3412
+ unit: "id";
3413
+ label: true;
3414
+ };
3415
+ events: {
3416
+ description: string;
3417
+ unit: "count";
3418
+ };
3419
+ xr_interactions: {
3420
+ description: string;
3421
+ unit: "count";
3422
+ measure: true;
3423
+ };
3424
+ started_at: {
3425
+ description: string;
3426
+ unit: "timestamp";
3427
+ };
3428
+ ended_at: {
3429
+ description: string;
3430
+ unit: "timestamp";
3431
+ };
3432
+ };
3433
+ limits: {
3434
+ maxRows: number;
3435
+ maxSummaryRows: number;
3436
+ };
3437
+ interpretation: string;
3438
+ caveats: string[];
3439
+ sourceChannels: ("pointer_move" | "pointer_click" | "mesh_interaction")[];
3440
+ related: ("list_sessions" | "xr_rotation" | "xr_locomotion" | "xr_tracking_quality")[];
3441
+ comparable: {
3442
+ primary: string;
3443
+ direction: "up";
3444
+ minSample: number;
3445
+ };
3446
+ category: "xr";
3447
+ };
3448
+ xr_locomotion: {
3449
+ id: "xr_locomotion";
3450
+ title: string;
3451
+ description: string;
3452
+ builder: "buildXrLocomotionComfort";
3453
+ endpoint: {
3454
+ method: "GET";
3455
+ path: string;
3456
+ };
3457
+ grain: "session";
3458
+ dimensions: ("scene" | "session")[];
3459
+ filters: ("scene" | "session" | "since" | "until" | "bins" | "limit" | "format")[];
3460
+ row: z.ZodObject<{
3461
+ session_id: z.ZodString;
3462
+ fly_gestures: z.ZodNumber;
3463
+ navigate_gestures: z.ZodNumber;
3464
+ teleports: z.ZodNumber;
3465
+ locomotion_ms: z.ZodNumber;
3466
+ started_at: z.ZodString;
3467
+ ended_at: z.ZodString;
3468
+ }, z.core.$strip>;
3469
+ columns: {
3470
+ session_id: {
3471
+ description: string;
3472
+ unit: "id";
3473
+ label: true;
3474
+ };
3475
+ fly_gestures: {
3476
+ description: string;
3477
+ unit: "count";
3478
+ };
3479
+ navigate_gestures: {
3480
+ description: string;
3481
+ unit: "count";
3482
+ };
3483
+ teleports: {
3484
+ description: string;
3485
+ unit: "count";
3486
+ };
3487
+ locomotion_ms: {
3488
+ description: string;
3489
+ unit: "ms";
3490
+ measure: true;
3491
+ };
3492
+ started_at: {
3493
+ description: string;
3494
+ unit: "timestamp";
3495
+ };
3496
+ ended_at: {
3497
+ description: string;
3498
+ unit: "timestamp";
3499
+ };
3500
+ };
3501
+ limits: {
3502
+ maxRows: number;
3503
+ maxSummaryRows: number;
3504
+ };
3505
+ interpretation: string;
3506
+ caveats: string[];
3507
+ sourceChannels: ("camera_gesture" | "mesh_interaction")[];
3508
+ related: ("xr_rotation" | "xr_abandonment" | "camera_gestures" | "xr_boundary_contacts")[];
3509
+ comparable: {
3510
+ primary: string;
3511
+ direction: "down";
3512
+ minSample: number;
3513
+ };
3514
+ category: "xr";
3515
+ };
3516
+ xr_tracking_quality: {
3517
+ id: "xr_tracking_quality";
3518
+ title: string;
3519
+ description: string;
3520
+ builder: "buildTrackingQuality";
3521
+ endpoint: {
3522
+ method: "GET";
3523
+ path: string;
3524
+ };
3525
+ grain: "session";
3526
+ dimensions: ("scene" | "session" | "source")[];
3527
+ filters: ("scene" | "session" | "since" | "until" | "bins" | "limit" | "format")[];
3528
+ row: z.ZodObject<{
3529
+ session_id: z.ZodString;
3530
+ degraded_ms: z.ZodNumber;
3531
+ hand_degraded_ms: z.ZodNumber;
3532
+ controller_degraded_ms: z.ZodNumber;
3533
+ degraded_episodes: z.ZodNumber;
3534
+ started_at: z.ZodString;
3535
+ ended_at: z.ZodString;
3536
+ }, z.core.$strip>;
3537
+ columns: {
3538
+ session_id: {
3539
+ description: string;
3540
+ unit: "id";
3541
+ label: true;
3542
+ };
3543
+ degraded_ms: {
3544
+ description: string;
3545
+ unit: "ms";
3546
+ measure: true;
3547
+ };
3548
+ hand_degraded_ms: {
3549
+ description: string;
3550
+ unit: "ms";
3551
+ };
3552
+ controller_degraded_ms: {
3553
+ description: string;
3554
+ unit: "ms";
3555
+ };
3556
+ degraded_episodes: {
3557
+ description: string;
3558
+ unit: "count";
3559
+ };
3560
+ started_at: {
3561
+ description: string;
3562
+ unit: "timestamp";
3563
+ };
3564
+ ended_at: {
3565
+ description: string;
3566
+ unit: "timestamp";
3567
+ };
3568
+ };
3569
+ limits: {
3570
+ maxRows: number;
3571
+ maxSummaryRows: number;
3572
+ };
3573
+ interpretation: string;
3574
+ caveats: string[];
3575
+ sourceChannels: "capability_change"[];
3576
+ related: ("xr_sources" | "xr_abandonment" | "xr_locomotion" | "capability_changes")[];
3577
+ comparable: {
3578
+ primary: string;
3579
+ direction: "down";
3580
+ minSample: number;
3581
+ };
3582
+ category: "xr";
3583
+ };
3584
+ boundary_heatmap: {
3585
+ id: "boundary_heatmap";
3586
+ title: string;
3587
+ description: string;
3588
+ builder: "buildBoundaryHeatmap";
3589
+ endpoint: {
3590
+ method: "GET";
3591
+ path: string;
3592
+ };
3593
+ grain: "voxel";
3594
+ dimensions: ("scene" | "session")[];
3595
+ filters: ("scene" | "session" | "since" | "until" | "region" | "limit" | "cellSize" | "format")[];
3596
+ row: z.ZodObject<{
3597
+ vx: z.ZodNumber;
3598
+ vy: z.ZodNumber;
3599
+ vz: z.ZodNumber;
3600
+ count: z.ZodNumber;
3601
+ }, z.core.$strip>;
3602
+ columns: {
3603
+ vx: {
3604
+ description: string;
3605
+ unit: "index";
3606
+ label: true;
3607
+ };
3608
+ vy: {
3609
+ description: string;
3610
+ unit: "index";
3611
+ };
3612
+ vz: {
3613
+ description: string;
3614
+ unit: "index";
3615
+ };
3616
+ count: {
3617
+ description: string;
3618
+ unit: "count";
3619
+ measure: true;
3620
+ };
3621
+ };
3622
+ limits: {
3623
+ maxRows: number;
3624
+ maxSummaryRows: number;
3625
+ };
3626
+ interpretation: string;
3627
+ caveats: string[];
3628
+ sourceChannels: "xr_boundary_proximity"[];
3629
+ related: ("xr_locomotion" | "position_heatmap" | "boundary_heatmap_stats" | "xr_boundary_contacts")[];
3630
+ comparable: {
3631
+ primary: string;
3632
+ direction: "down";
3633
+ minSample: number;
3634
+ };
3635
+ category: "xr";
3636
+ };
3637
+ boundary_heatmap_stats: {
3638
+ id: "boundary_heatmap_stats";
3639
+ title: string;
3640
+ description: string;
3641
+ builder: "buildBoundaryHeatmapStats";
3642
+ endpoint: {
3643
+ method: "GET";
3644
+ path: string;
3645
+ };
3646
+ grain: "project";
3647
+ dimensions: ("scene" | "session")[];
3648
+ filters: ("scene" | "session" | "since" | "until" | "region" | "cellSize" | "format")[];
3649
+ row: z.ZodObject<{
3650
+ cells: z.ZodNumber;
3651
+ hits: z.ZodNumber;
3652
+ }, z.core.$strip>;
3653
+ columns: {
3654
+ cells: {
3655
+ description: string;
3656
+ unit: "count";
3657
+ };
3658
+ hits: {
3659
+ description: string;
3660
+ unit: "count";
3661
+ measure: true;
3662
+ };
3663
+ };
3664
+ limits: {
3665
+ maxRows: number;
3666
+ maxSummaryRows: number;
3667
+ };
3668
+ interpretation: string;
3669
+ caveats: string[];
3670
+ sourceChannels: "xr_boundary_proximity"[];
3671
+ related: "boundary_heatmap"[];
3672
+ category: "xr";
3673
+ };
3674
+ xr_boundary_contacts: {
3675
+ id: "xr_boundary_contacts";
3676
+ title: string;
3677
+ description: string;
3678
+ builder: "buildBoundaryContacts";
3679
+ endpoint: {
3680
+ method: "GET";
3681
+ path: string;
3682
+ };
3683
+ grain: "session";
3684
+ dimensions: ("scene" | "session")[];
3685
+ filters: ("scene" | "session" | "since" | "until" | "bins" | "limit" | "format")[];
3686
+ row: z.ZodObject<{
3687
+ session_id: z.ZodString;
3688
+ contacts: z.ZodNumber;
3689
+ near_ms: z.ZodNumber;
3690
+ }, z.core.$strip>;
3691
+ columns: {
3692
+ session_id: {
3693
+ description: string;
3694
+ unit: "id";
3695
+ label: true;
3696
+ };
3697
+ contacts: {
3698
+ description: string;
3699
+ unit: "count";
3700
+ measure: true;
3701
+ };
3702
+ near_ms: {
3703
+ description: string;
3704
+ unit: "ms";
3705
+ };
3706
+ };
3707
+ limits: {
3708
+ maxRows: number;
3709
+ maxSummaryRows: number;
3710
+ };
3711
+ interpretation: string;
3712
+ caveats: string[];
3713
+ sourceChannels: "xr_boundary_proximity"[];
3714
+ related: ("xr_abandonment" | "xr_locomotion" | "boundary_heatmap")[];
3715
+ comparable: {
3716
+ primary: string;
3717
+ direction: "down";
3718
+ minSample: number;
3719
+ };
3720
+ category: "xr";
3721
+ };
3722
+ ar_placement_time_to_place: {
3723
+ id: "ar_placement_time_to_place";
3724
+ title: string;
3725
+ description: string;
3726
+ builder: "buildArPlacementTimeToPlace";
3727
+ endpoint: {
3728
+ method: "GET";
3729
+ path: string;
3730
+ };
3731
+ grain: "bucket";
3732
+ dimensions: ("scene" | "session")[];
3733
+ filters: ("scene" | "session" | "since" | "until" | "bins" | "limit" | "bucketMs" | "format")[];
3734
+ row: z.ZodObject<{
3735
+ bucket: z.ZodNumber;
3736
+ placements: z.ZodNumber;
3737
+ }, z.core.$strip>;
3738
+ columns: {
3739
+ bucket: {
3740
+ description: string;
3741
+ unit: "ms";
3742
+ label: true;
3743
+ axis: true;
3744
+ };
3745
+ placements: {
3746
+ description: string;
3747
+ unit: "count";
3748
+ measure: true;
3749
+ };
3750
+ };
3751
+ limits: {
3752
+ maxRows: number;
3753
+ maxSummaryRows: number;
3754
+ };
3755
+ interpretation: string;
3756
+ caveats: string[];
3757
+ sourceChannels: "ar_placement"[];
3758
+ related: ("ar_placement_attempts" | "ar_placement_surfaces")[];
3759
+ comparable: {
3760
+ primary: string;
3761
+ direction: "neutral";
3762
+ minSample: number;
3763
+ };
3764
+ category: "ar";
3765
+ };
3766
+ ar_placement_attempts: {
3767
+ id: "ar_placement_attempts";
3768
+ title: string;
3769
+ description: string;
3770
+ builder: "buildArPlacementAttempts";
3771
+ endpoint: {
3772
+ method: "GET";
3773
+ path: string;
3774
+ };
3775
+ grain: "bucket";
3776
+ dimensions: ("scene" | "session")[];
3777
+ filters: ("scene" | "session" | "since" | "until" | "bins" | "limit" | "format")[];
3778
+ row: z.ZodObject<{
3779
+ attempts: z.ZodNumber;
3780
+ placements: z.ZodNumber;
3781
+ }, z.core.$strip>;
3782
+ columns: {
3783
+ attempts: {
3784
+ description: string;
3785
+ unit: "count";
3786
+ label: true;
3787
+ axis: true;
3788
+ };
3789
+ placements: {
3790
+ description: string;
3791
+ unit: "count";
3792
+ measure: true;
3793
+ };
3794
+ };
3795
+ limits: {
3796
+ maxRows: number;
3797
+ maxSummaryRows: number;
3798
+ };
3799
+ interpretation: string;
3800
+ caveats: string[];
3801
+ sourceChannels: "ar_placement"[];
3802
+ related: ("ar_placement_time_to_place" | "ar_placement_surfaces")[];
3803
+ comparable: {
3804
+ primary: string;
3805
+ direction: "neutral";
3806
+ minSample: number;
3807
+ };
3808
+ category: "ar";
3809
+ };
3810
+ ar_placement_surfaces: {
3811
+ id: "ar_placement_surfaces";
3812
+ title: string;
3813
+ description: string;
3814
+ builder: "buildArPlacementSurfaces";
3815
+ endpoint: {
3816
+ method: "GET";
3817
+ path: string;
3818
+ };
3819
+ grain: "row";
3820
+ dimensions: ("scene" | "session")[];
3821
+ filters: ("scene" | "session" | "since" | "until" | "bins" | "limit" | "format")[];
3822
+ row: z.ZodObject<{
3823
+ surface: z.ZodString;
3824
+ placements: z.ZodNumber;
3825
+ avg_scale: z.ZodNumber;
3826
+ }, z.core.$strip>;
3827
+ columns: {
3828
+ surface: {
3829
+ description: string;
3830
+ unit: "label";
3831
+ label: true;
3832
+ };
3833
+ placements: {
3834
+ description: string;
3835
+ unit: "count";
3836
+ measure: true;
3837
+ };
3838
+ avg_scale: {
3839
+ description: string;
3840
+ unit: "ratio";
3841
+ };
3842
+ };
3843
+ limits: {
3844
+ maxRows: number;
3845
+ maxSummaryRows: number;
3846
+ };
3847
+ interpretation: string;
3848
+ caveats: string[];
3849
+ sourceChannels: "ar_placement"[];
3850
+ related: ("ar_placement_time_to_place" | "ar_placement_attempts")[];
3851
+ comparable: {
3852
+ primary: string;
3853
+ direction: "neutral";
3854
+ minSample: number;
3855
+ };
3856
+ category: "ar";
3857
+ };
3858
+ funnel: {
3859
+ id: "funnel";
3860
+ title: string;
3861
+ description: string;
3862
+ builder: "buildFunnel";
3863
+ endpoint: {
3864
+ method: "GET";
3865
+ path: string;
3866
+ };
3867
+ grain: "bucket";
3868
+ dimensions: ("scene" | "cameraMode")[];
3869
+ filters: ("scene" | "cameraMode" | "since" | "until" | "steps" | "format")[];
3870
+ row: z.ZodObject<{
3871
+ step: z.ZodNumber;
3872
+ sessions: z.ZodNumber;
3873
+ }, z.core.$strip>;
3874
+ columns: {
3875
+ step: {
3876
+ description: string;
3877
+ unit: "index";
3878
+ label: true;
3879
+ axis: true;
3880
+ };
3881
+ sessions: {
3882
+ description: string;
3883
+ unit: "sessions";
3884
+ measure: true;
3885
+ };
3886
+ };
3887
+ limits: {
3888
+ maxRows: number;
3889
+ maxSummaryRows: number;
3890
+ };
3891
+ interpretation: string;
3892
+ caveats: string[];
3893
+ sourceChannels: never[];
3894
+ related: ("scene_retention" | "load_bounce_funnel" | "variant_leaderboard")[];
3895
+ comparable: {
3896
+ primary: string;
3897
+ direction: "up";
3898
+ minSample: number;
3899
+ };
3900
+ category: "conversion";
3901
+ };
3902
+ scene_retention: {
3903
+ id: "scene_retention";
3904
+ title: string;
3905
+ description: string;
3906
+ builder: "buildSceneRetention";
3907
+ endpoint: {
3908
+ method: "GET";
3909
+ path: string;
3910
+ };
3911
+ grain: "row";
3912
+ dimensions: "scene"[];
3913
+ filters: ("since" | "until" | "limit" | "format")[];
3914
+ row: z.ZodObject<{
3915
+ from_scene: z.ZodString;
3916
+ to_scene: z.ZodString;
3917
+ sessions: z.ZodNumber;
3918
+ }, z.core.$strip>;
3919
+ columns: {
3920
+ from_scene: {
3921
+ description: string;
3922
+ unit: "id";
3923
+ label: true;
3924
+ };
3925
+ to_scene: {
3926
+ description: string;
3927
+ unit: "id";
3928
+ };
3929
+ sessions: {
3930
+ description: string;
3931
+ unit: "sessions";
3932
+ measure: true;
3933
+ };
3934
+ };
3935
+ limits: {
3936
+ maxRows: number;
3937
+ maxSummaryRows: number;
3938
+ };
3939
+ interpretation: string;
3940
+ caveats: string[];
3941
+ sourceChannels: "scene_change"[];
3942
+ related: ("list_scenes" | "funnel" | "load_bounce_funnel")[];
3943
+ comparable: {
3944
+ primary: string;
3945
+ direction: "up";
3946
+ minSample: number;
3947
+ };
3948
+ category: "conversion";
3949
+ };
3950
+ load_bounce_funnel: {
3951
+ id: "load_bounce_funnel";
3952
+ title: string;
3953
+ description: string;
3954
+ builder: "buildLoadBounceFunnel";
3955
+ endpoint: {
3956
+ method: "GET";
3957
+ path: string;
3958
+ };
3959
+ grain: "bucket";
3960
+ dimensions: "scene"[];
3961
+ filters: ("scene" | "since" | "until" | "bands" | "format")[];
3962
+ row: z.ZodObject<{
3963
+ band: z.ZodNumber;
3964
+ sessions: z.ZodNumber;
3965
+ bounced: z.ZodNumber;
3966
+ }, z.core.$strip>;
3967
+ columns: {
3968
+ band: {
3969
+ description: string;
3970
+ unit: "index";
3971
+ label: true;
3972
+ axis: true;
3973
+ };
3974
+ sessions: {
3975
+ description: string;
3976
+ unit: "sessions";
3977
+ };
3978
+ bounced: {
3979
+ description: string;
3980
+ unit: "sessions";
3981
+ measure: true;
3982
+ rateOf: string;
3983
+ };
3984
+ };
3985
+ limits: {
3986
+ maxRows: number;
3987
+ maxSummaryRows: number;
3988
+ };
3989
+ interpretation: string;
3990
+ caveats: string[];
3991
+ sourceChannels: ("pointer_click" | "camera_gesture" | "mesh_interaction" | "asset_load")[];
3992
+ related: ("funnel" | "perf_churn" | "compile_stalls" | "scene_retention")[];
3993
+ comparable: {
3994
+ primary: string;
3995
+ direction: "down";
3996
+ minSample: number;
3997
+ };
3998
+ category: "conversion";
3999
+ };
4000
+ variant_leaderboard: {
4001
+ id: "variant_leaderboard";
4002
+ title: string;
4003
+ description: string;
4004
+ builder: "buildVariantLeaderboard";
4005
+ endpoint: {
4006
+ method: "GET";
4007
+ path: string;
4008
+ };
4009
+ grain: "row";
4010
+ dimensions: ("scene" | "name" | "cameraMode")[];
4011
+ filters: ("scene" | "cameraMode" | "since" | "until" | "limit" | "variant" | "conversion" | "format")[];
4012
+ row: z.ZodObject<{
4013
+ variant: z.ZodString;
4014
+ views: z.ZodNumber;
4015
+ sessions: z.ZodNumber;
4016
+ conversions: z.ZodNumber;
4017
+ avg_dwell_ms: z.ZodNumber;
4018
+ }, z.core.$strip>;
4019
+ columns: {
4020
+ variant: {
4021
+ description: string;
4022
+ unit: "label";
4023
+ label: true;
4024
+ };
4025
+ views: {
4026
+ description: string;
4027
+ unit: "count";
4028
+ measure: true;
4029
+ };
4030
+ sessions: {
4031
+ description: string;
4032
+ unit: "sessions";
4033
+ };
4034
+ conversions: {
4035
+ description: string;
4036
+ unit: "sessions";
4037
+ rateOf: string;
4038
+ };
4039
+ avg_dwell_ms: {
4040
+ description: string;
4041
+ unit: "ms";
4042
+ };
4043
+ };
4044
+ limits: {
4045
+ maxRows: number;
4046
+ maxSummaryRows: number;
4047
+ };
4048
+ interpretation: string;
4049
+ caveats: string[];
4050
+ sourceChannels: "custom"[];
4051
+ related: ("top_meshes" | "funnel" | "scene_retention")[];
4052
+ comparable: {
4053
+ primary: string;
4054
+ direction: "up";
4055
+ minSample: number;
4056
+ };
4057
+ category: "conversion";
4058
+ };
4059
+ };
4060
+ /** The registry's own type, with each entry's literal `builder` preserved. */
4061
+ export type MetricRegistry = typeof METRIC_REGISTRY;
4062
+ /**
4063
+ * Every `build*` aggregation that a registry entry claims. Derived from the
4064
+ * literal `builder` values, which is why {@link METRIC_REGISTRY} is declared with
4065
+ * `satisfies` rather than a type annotation.
4066
+ */
4067
+ type RegisteredBuilderName = {
4068
+ [K in MetricId]: MetricRegistry[K] extends {
4069
+ builder: infer B extends string;
4070
+ } ? B : never;
4071
+ }[MetricId];
4072
+ /**
4073
+ * Names in {@link AGGREGATION_BUILDER_NAMES} that no registry entry claims.
4074
+ */
4075
+ export type UnregisteredAggregation = Exclude<AggregationBuilderName, RegisteredBuilderName>;
4076
+ /** Fails to compile unless `T` is `never`; the error names the offending member. */
4077
+ type AssertNever<T extends never> = T;
4078
+ /**
4079
+ * **Compile-time coverage guard (design sketch §A.3).** If you add a `build*`
4080
+ * aggregation to {@link AGGREGATION_BUILDER_NAMES} without a registry entry,
4081
+ * this line fails to typecheck and names the missing builder. Add the entry — a
4082
+ * new aggregation is not done until it has one. The runtime companions are this
4083
+ * package's `src/__tests__/registry.test.ts` (entry ↔ list) and `@uptimizr/db`'s
4084
+ * `src/__tests__/registry.test.ts` (list ↔ the real `build*` exports).
4085
+ */
4086
+ export type NoUnregisteredAggregations = AssertNever<UnregisteredAggregation>;
4087
+ /** Every registry id, in declaration order. */
4088
+ export declare const METRIC_IDS: readonly MetricId[];
4089
+ /** Narrow an arbitrary string to a {@link MetricId}. */
4090
+ export declare function isMetricId(value: string): value is MetricId;
4091
+ /** Look a metric up by id, or `undefined` when the id is unknown. */
4092
+ export declare function getMetric(id: string): MetricDefinition | undefined;
4093
+ /** Every registry entry as a plain array, typed as the shared interface. */
4094
+ export declare function allMetrics(): readonly MetricDefinition[];
4095
+ /**
4096
+ * Reverse lookup: aggregation builder name → the metric that claims it.
4097
+ *
4098
+ * `MetricDefinition.builder` is the forward direction (a metric names its
4099
+ * builder); this is the direction the *store edge* needs — a `QuerySpec` knows
4100
+ * which aggregation produced it, and numeric coercion has to find that
4101
+ * aggregation's row schema (ADR 0051 §2). Built once, at module load: the
4102
+ * compile-time coverage guard below makes the mapping total over every exported
4103
+ * `build*`, and every builder is claimed by exactly one metric (asserted in
4104
+ * `src/__tests__/registry.test.ts`).
4105
+ */
4106
+ export declare const METRIC_BY_BUILDER: ReadonlyMap<AggregationBuilderName, MetricDefinition>;
4107
+ /**
4108
+ * The registry entry that claims a given aggregation builder, or `undefined` for
4109
+ * the (currently empty) set of unclaimed builders.
4110
+ */
4111
+ export declare function metricForBuilder(builder: AggregationBuilderName): MetricDefinition | undefined;
4112
+ /**
4113
+ * A **resource** entry is a store read rather than an aggregation: it has no
4114
+ * `build*` builder, no time range, and is included so the generated agent
4115
+ * catalog stays a superset of the hand-written one (design sketch §A.4).
4116
+ */
4117
+ export declare function isResourceMetric(metric: MetricDefinition): boolean;
4118
+ export {};
4119
+ //# sourceMappingURL=registry.d.ts.map