@opengeni/observability 0.8.6-canary.2 → 0.8.8-canary.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.
package/dist/index.d.ts CHANGED
@@ -121,6 +121,7 @@ export declare class Observability {
121
121
  private readonly gauges;
122
122
  private readonly histograms;
123
123
  private readonly registrations;
124
+ private readonly pendingExports;
124
125
  private readonly now;
125
126
  private readonly exporter;
126
127
  private readonly resourceAttributes;
@@ -176,6 +177,8 @@ export declare class Observability {
176
177
  buckets?: number[];
177
178
  }): void;
178
179
  prometheusMetrics(): Promise<string>;
180
+ /** Wait for every OTLP export accepted before or during this drain. */
181
+ flush(): Promise<void>;
179
182
  private counter;
180
183
  private gauge;
181
184
  private histogram;
package/dist/index.js CHANGED
@@ -250,7 +250,21 @@ var PUBLIC_CHANNEL_A_FAILURE_REASONS = /* @__PURE__ */ new Set([
250
250
  "request_rejected",
251
251
  "unexpected"
252
252
  ]);
253
+ var PUBLIC_API_FATAL_PHASES = /* @__PURE__ */ new Set(["startup", "running"]);
254
+ var PUBLIC_API_FATAL_REASON_KINDS = /* @__PURE__ */ new Set([
255
+ "bigint",
256
+ "boolean",
257
+ "error",
258
+ "function",
259
+ "null",
260
+ "number",
261
+ "object",
262
+ "string",
263
+ "symbol",
264
+ "undefined"
265
+ ]);
253
266
  var PUBLIC_TELEMETRY_ERROR_CLASSES = /* @__PURE__ */ new Set([
267
+ "ApiFatalOperationError",
254
268
  "OperationError",
255
269
  "CodexCheckpointOperationError",
256
270
  "CodexFleetShadowOperationError",
@@ -283,6 +297,9 @@ var PUBLIC_TELEMETRY_ERROR_CLASSES = /* @__PURE__ */ new Set([
283
297
  ]);
284
298
  var PUBLIC_TELEMETRY_ERROR_CODES = /* @__PURE__ */ new Set([
285
299
  "agent_command_wake_failed",
300
+ "api_startup_failed",
301
+ "api_uncaught_exception",
302
+ "api_unhandled_rejection",
286
303
  "artifact_materializer_native_input_framing_failed",
287
304
  "artifact_materializer_native_snapshot_open_failed",
288
305
  "artifact_materializer_native_state_mismatch",
@@ -400,6 +417,7 @@ var Observability = class {
400
417
  gauges = /* @__PURE__ */ new Map();
401
418
  histograms = /* @__PURE__ */ new Map();
402
419
  registrations = /* @__PURE__ */ new Map();
420
+ pendingExports = /* @__PURE__ */ new Set();
403
421
  now;
404
422
  exporter;
405
423
  resourceAttributes;
@@ -604,6 +622,12 @@ var Observability = class {
604
622
  }
605
623
  return await this.registry.metrics();
606
624
  }
625
+ /** Wait for every OTLP export accepted before or during this drain. */
626
+ async flush() {
627
+ while (this.pendingExports.size > 0) {
628
+ await Promise.allSettled([...this.pendingExports]);
629
+ }
630
+ }
607
631
  counter(name, help, labelNames) {
608
632
  const existing = this.counters.get(name);
609
633
  if (existing) {
@@ -684,15 +708,19 @@ var Observability = class {
684
708
  }
685
709
  ]
686
710
  };
687
- void this.exporter(endpoint, body, parseHeaders(this.settings.observabilityOtlpHeaders)).catch(
688
- () => {
689
- this.warn("OTLP span export failed", {
690
- errorClass: "TelemetryExportError",
691
- errorCode: "otlp_export_failed",
692
- origin: "observability"
693
- });
694
- }
695
- );
711
+ let pendingExport;
712
+ pendingExport = Promise.resolve().then(
713
+ () => this.exporter(endpoint, body, parseHeaders(this.settings.observabilityOtlpHeaders))
714
+ ).catch(() => {
715
+ this.warn("OTLP span export failed", {
716
+ errorClass: "TelemetryExportError",
717
+ errorCode: "otlp_export_failed",
718
+ origin: "observability"
719
+ });
720
+ }).finally(() => {
721
+ this.pendingExports.delete(pendingExport);
722
+ });
723
+ this.pendingExports.add(pendingExport);
696
724
  }
697
725
  };
698
726
  function sandboxOperationMetricObserver(observability) {
@@ -877,6 +905,7 @@ function projectPublicTelemetryAttributes(attributes) {
877
905
  return {
878
906
  ...projectStartupDependencyAttributes(attributes),
879
907
  ...projectPublicChannelADiagnosticAttributes(attributes),
908
+ ...projectApiFatalDiagnosticAttributes(attributes),
880
909
  ...projectPublicDiagnosticAttributes(attributes)
881
910
  };
882
911
  }
@@ -889,6 +918,15 @@ function projectPublicTelemetryAttributes(attributes) {
889
918
  })
890
919
  );
891
920
  }
921
+ function projectApiFatalDiagnosticAttributes(attributes) {
922
+ if (attributes.errorClass !== "ApiFatalOperationError") return {};
923
+ const phase = attributes.phase;
924
+ const reasonKind = attributes.reasonKind;
925
+ return {
926
+ ...typeof phase === "string" && PUBLIC_API_FATAL_PHASES.has(phase) ? { phase } : {},
927
+ ...typeof reasonKind === "string" && PUBLIC_API_FATAL_REASON_KINDS.has(reasonKind) ? { reasonKind } : {}
928
+ };
929
+ }
892
930
  function projectStartupDependencyAttributes(attributes) {
893
931
  if (attributes.errorClass !== "StartupDependencyError" || attributes.errorCode !== "startup_dependency_retry") {
894
932
  return {};
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { collectDefaultMetrics, Counter, Gauge, Histogram, Registry } from \"prom-client\";\nimport { SandboxBackend } from \"@opengeni/contracts\";\n\nexport type AttributeValue = string | number | boolean | null | undefined;\nexport type Attributes = Record<string, AttributeValue>;\n\nexport type ObservabilitySettings = {\n serviceName: string;\n environment: string;\n deploymentRevision?: string | undefined;\n observabilityStructuredLogs: boolean;\n observabilityMetricsEnabled: boolean;\n observabilityOtlpEndpoint?: string | undefined;\n observabilityOtlpHeaders: string;\n sandboxOwnershipEnabled?: boolean | undefined;\n sandboxLazyProvisionEnabled?: boolean | undefined;\n rigVerificationLeaseOwnershipEnabled?: boolean | undefined;\n};\n\nexport type ObservabilityOptions = {\n component: string;\n now?: () => number;\n exporter?: (url: string, body: unknown, headers: Record<string, string>) => Promise<void>;\n};\n\nexport type Span = {\n traceId: string;\n spanId: string;\n end: (input?: { attributes?: Attributes; error?: unknown }) => void;\n};\n\nexport type MetricLabels = Record<string, AttributeValue>;\n\n/**\n * Stable, non-reversible correlation key for one logical sandbox lease. Public\n * telemetry intentionally drops workspace/group identifiers; this key lets an\n * operator correlate API, worker, and reaper failures without publishing\n * either UUID. The domain separator prevents reuse as a generic identifier\n * digest.\n */\nexport function sandboxLeaseTelemetryKey(workspaceId: string, sandboxGroupId: string): string {\n return `slk_${createHash(\"sha256\")\n .update(\"opengeni:sandbox-lease-telemetry:v1\\0\")\n .update(workspaceId)\n .update(\"\\0\")\n .update(sandboxGroupId)\n .digest(\"hex\")\n .slice(0, 32)}`;\n}\n\n/**\n * Stable selectors shared by OpenGeni's runtime metrics and optional\n * Prometheus/Grafana distribution. Operators can use these values for custom\n * namespaces and dashboard ConfigMaps without duplicating chart internals.\n */\nexport const OPENGENI_OBSERVABILITY_DISTRIBUTION = {\n monitoringNamespaceLabel: \"opengeni.ai/monitoring\",\n monitoringNamespaceLabelValue: \"enabled\",\n grafanaDashboardLabel: \"grafana_dashboard\",\n grafanaDashboardLabelValue: \"1\",\n} as const;\n\nconst httpHistogramBuckets = [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10];\nconst durationHistogramBuckets = [\n 0.01, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10, 30, 60, 120, 300, 900, 1800, 3600,\n];\n\nconst SANDBOX_OPERATION_BACKENDS = new Set<string>([...SandboxBackend.options, \"unprovisioned\"]);\n\nconst SANDBOX_OPERATION_NAMES = new Set([\n \"desktopInput\",\n \"screenshot\",\n \"exec\",\n \"execCommand\",\n \"writeStdin\",\n \"cancelExecCommand\",\n \"readFile\",\n \"writeFile\",\n \"listDir\",\n \"pathExists\",\n \"viewImage\",\n \"materializeEntry\",\n \"editor.createFile\",\n \"editor.updateFile\",\n \"editor.deleteFile\",\n \"resolveExposedPort\",\n \"serializeSessionState\",\n]);\n\n/**\n * Closed set of organization-tenancy compatibility lanes (the tenancy\n * migration's validate phase; see `docs/organization-tenancy.md`).\n *\n * Each entry names one legacy behaviour a live request can still take today.\n * The metric built from them is deliberately a COUNTER of lane USES, and it\n * measures exactly one thing: **is this lane still being exercised?** That is\n * the question the tenancy cutover gate (\"zero incompatible writers\") actually\n * asks, and it is answerable.\n *\n * It is emphatically NOT a burndown of unmigrated rows, and must never be\n * relabelled as one. Every one of these lanes is still *open*: the live write\n * paths keep producing rows in it, so no row-count predicate over any of them\n * can reach zero and a backlog gauge would read as a permanent, untruthful\n * unmigrated backlog. `docs/organization-tenancy.md` records, per lane, why -\n * including the lanes deliberately left uninstrumented because no truthful\n * signal exists for them yet.\n *\n * The recorded value is the lane name and nothing else. No organization,\n * workspace, session, subject, connection, or resource identity, and no\n * credential, name, or content, may ever become a label here.\n */\nexport const TENANCY_COMPATIBILITY_LANES = [\n /**\n * A provider connection carrying `authority_scope = 'legacy_user'` was\n * resolved for accepted use: a personal row with no common authority or\n * grant, admitted through `legacy_user_compatibility` provenance instead of\n * an explicit delegation. Migration 0256 backfilled the existing rows, but\n * its `bind_connection_authority` trigger still classifies a NEW personal\n * connection this way whenever the inserting subject has no active\n * organization membership, so this counter is expected to stay above zero\n * until that classification changes. That is the finding, not a defect.\n */\n \"connection_legacy_user\",\n /**\n * A workspace-scope connection ref carried no connection id, so the\n * accepted-use authority (migration 0279) could not identify the exact row\n * and the request fell back to the unprivileged pre-snapshot resolution.\n * This lane writes no `connection_use_audit_facts` row and leaves no durable\n * trace of any kind, so a use counter is the only possible evidence it was\n * taken at all.\n */\n \"connection_pre_snapshot_ref\",\n /**\n * A NEW persistable `/workspace` mutation was refused because the writer\n * behind it has no recorded authority (`authority_unattributed`): either a\n * direct request whose principal froze the pre-0096 legacy initiator, or a\n * retained process whose pre-0277 row has no tenancy half. This counts\n * REFUSED MUTATIONS, not unattributed rows - the turn and process admission\n * lanes deliberately still accept a `legacy_unattributed` initiator, and\n * nothing may invent the missing authority or disturb the running provider\n * process.\n */\n \"workspace_writer_unattributed\",\n] as const;\nexport type TenancyCompatibilityLane = (typeof TENANCY_COMPATIBILITY_LANES)[number];\n\nconst TENANCY_COMPATIBILITY_LANE_SET = new Set<string>(TENANCY_COMPATIBILITY_LANES);\n\nconst TENANCY_COMPATIBILITY_LANE_METRIC = {\n name: \"opengeni_tenancy_compatibility_lane_uses_total\",\n help: \"Live uses of an organization-tenancy compatibility lane, by lane.\",\n} as const;\n\n/**\n * Record one live use of a tenancy compatibility lane. Fail-safe by\n * construction: telemetry must never change an authorization or credential\n * outcome, so a registry failure is counted best-effort and swallowed here.\n */\nexport function recordTenancyCompatibilityLaneUse(\n observability: Observability | null | undefined,\n lane: TenancyCompatibilityLane,\n): void {\n if (!observability) return;\n // An unreviewed lane name must not silently mint a new series.\n if (!TENANCY_COMPATIBILITY_LANE_SET.has(lane)) return;\n try {\n observability.incrementCounter({ ...TENANCY_COMPATIBILITY_LANE_METRIC, labels: { lane } });\n } catch {\n recordObserverFailure(observability, \"tenancy_compatibility_lane\");\n }\n}\n\nconst INTERACTION_RESOURCES = new Set([\"browser\", \"computer\"]);\nconst INTERACTION_OPERATIONS = new Set([\n \"create\",\n \"end\",\n \"suspend\",\n \"resume\",\n \"publish\",\n \"observe\",\n \"act\",\n \"open_target\",\n \"select_target\",\n \"close_target\",\n \"attach\",\n \"auth_start\",\n \"auth_report\",\n \"auth_fill\",\n \"auth_verify\",\n \"intervention_create\",\n \"intervention_resolve\",\n]);\nconst INTERACTION_OUTCOMES = new Set([\n \"prepared\",\n \"dispatched\",\n \"completed\",\n \"failed\",\n \"outcome_unknown\",\n \"stale\",\n \"cancelled\",\n]);\nconst INTERACTION_MODES = new Set([\n \"semantic\",\n \"coordinate\",\n \"keyboard\",\n \"clipboard\",\n \"permission\",\n \"lifecycle\",\n \"media\",\n \"auth\",\n \"human\",\n]);\nconst INTERACTION_AUTH_STATES = new Set([\n \"discovering\",\n \"awaiting_choice\",\n \"awaiting_secret\",\n \"awaiting_external_action\",\n \"working\",\n \"verified\",\n \"failed\",\n \"cancelled\",\n]);\nconst INTERACTION_INTERVENTION_KINDS = new Set([\n \"manual_login\",\n \"mfa\",\n \"external_action\",\n \"confirmation\",\n \"other\",\n]);\nconst INTERACTION_INTERVENTION_OUTCOMES = new Set([\n \"opened\",\n \"completed\",\n \"dismissed\",\n \"expired\",\n \"cancelled\",\n]);\nconst WORKSPACE_INSIGHTS_RANGES = new Set([\"today\", \"week\", \"month\", \"ytd\"]);\nconst WORKSPACE_INSIGHTS_OUTCOMES = new Set([\"completed\", \"failed\"]);\nconst workspaceInsightsDurationHistogramBuckets = [0.05, 0.1, 0.25, 0.5, 1, 1.5, 2, 3, 5, 10, 30];\nconst PUBLIC_STARTUP_DEPENDENCIES = new Set([\n \"Modal private-registry image\",\n \"NATS\",\n \"PostgreSQL runtime posture\",\n \"Temporal\",\n \"Temporal client\",\n \"Temporal schedule (file upload reaper)\",\n \"Temporal schedule (sandbox reaper)\",\n \"Temporal schedule (session-workflow wake dispatcher)\",\n \"Temporal schedule (site auth maintenance)\",\n]);\n\n/**\n * External logs and OTLP are public/third-party projections, not canonical\n * OpenGeni storage. Only this reviewed closed set of operational fields may\n * cross that boundary. Unknown keys are omitted regardless of their value, so\n * a new diagnostic, identifier, command, response, or provider field cannot\n * become public by accident. This is schema projection, never value inspection\n * or rewriting.\n */\nconst PUBLIC_TELEMETRY_ATTRIBUTE_KEYS = new Set([\n \"http.request.method\",\n \"http.response.status_code\",\n \"opengeni.route\",\n \"opengeni.duration_ms\",\n \"opengeni.finalization_duration_ms\",\n \"opengeni.trigger_kind\",\n \"opengeni.status\",\n \"error.type\",\n \"error.status_code\",\n \"method\",\n \"route\",\n \"status\",\n \"durationMs\",\n \"attempt\",\n \"attempts\",\n \"delayMs\",\n \"provider\",\n \"providerApi\",\n \"model\",\n \"inputTokens\",\n \"outputTokens\",\n \"cachedTokens\",\n \"cacheWriteTokens\",\n \"reasoningTokens\",\n \"accountChangedFromPrevCall\",\n \"rejectedFields\",\n \"dependency\",\n \"activity\",\n \"backend\",\n \"op\",\n \"outcome\",\n \"eventType\",\n \"surface\",\n \"reason\",\n \"originalBytes\",\n \"deliveredBytes\",\n \"estimatedOriginalTokens\",\n \"estimatedDeliveredTokens\",\n \"fullEvidenceAvailable\",\n \"retainedOutputKind\",\n]);\n\n/** Opaque correlation fields require both a reviewed name and a closed value\n * grammar. Merely adding one to the ordinary allow-list would let an unrelated\n * caller accidentally publish a raw identifier under that name. */\nconst PUBLIC_TELEMETRY_OPAQUE_ATTRIBUTE_PATTERNS = new Map<string, RegExp>([\n [\"sandboxLeaseKey\", /^slk_[0-9a-f]{32}$/],\n [\"correlationId\", /^[A-Za-z0-9._:-]{1,128}$/],\n]);\n\nconst PUBLIC_CHANNEL_A_OPERATIONS = new Set([\n \"fs.list\",\n \"fs.list-batch\",\n \"fs.read\",\n \"fs.write\",\n \"fs.delete\",\n \"fs.move\",\n \"fs.mkdir\",\n \"git.status\",\n \"git.diff\",\n \"git.read-batch\",\n \"git.log\",\n \"git.show\",\n \"terminal.exec\",\n \"terminal.pty.open\",\n \"terminal.pty.write\",\n \"terminal.pty.resize\",\n \"terminal.pty.close\",\n \"read\",\n \"mutation\",\n]);\n\nconst PUBLIC_CHANNEL_A_FAILURE_REASONS = new Set([\n \"request_cancelled\",\n \"provider_read_busy\",\n \"provider_unavailable\",\n \"lifecycle_conflict\",\n \"request_rejected\",\n \"unexpected\",\n]);\n\n/**\n * Public diagnostic values are protocol constants, never values inferred from\n * an exception's name, constructor, code, message, or enumerable properties.\n * Unknown classes collapse to one fixed fallback; unknown codes and origins\n * are omitted rather than copied through based on syntax.\n */\nconst PUBLIC_TELEMETRY_ERROR_CLASSES = new Set([\n \"OperationError\",\n \"CodexCheckpointOperationError\",\n \"CodexFleetShadowOperationError\",\n \"ComputerActionTimeoutError\",\n \"ComputerUnavailableError\",\n \"CredentialRenewalOperationError\",\n \"CredentialReadOperationError\",\n \"EventPublishOperationError\",\n \"GitCredentialRenewalOperationError\",\n \"HostExportOperationError\",\n \"HttpOperationError\",\n \"McpLifecycleError\",\n \"McpOperationError\",\n \"MemoryEmbeddingOperationError\",\n \"MemorySearchOperationError\",\n \"NatsAuthCalloutOperationError\",\n \"OAuthOperationError\",\n \"RunCredentialRenewalOperationError\",\n \"RunStateCompatibilityError\",\n \"SandboxChannelAOperationError\",\n \"SnapshotOperationError\",\n \"StartupDependencyError\",\n \"TelemetryExportError\",\n \"CodemodeOperationError\",\n \"CodemodeTokenRenewalOperationError\",\n \"WorkerLifecycleOperation\",\n \"WorkerLifecycleOperationError\",\n \"WorkerOperationError\",\n \"WorkflowWakeOperationError\",\n]);\n\nconst PUBLIC_TELEMETRY_ERROR_CODES = new Set([\n \"agent_command_wake_failed\",\n \"artifact_materializer_native_input_framing_failed\",\n \"artifact_materializer_native_snapshot_open_failed\",\n \"artifact_materializer_native_state_mismatch\",\n \"artifact_materializer_source_content_type_mismatch\",\n \"artifact_materializer_source_open_failed\",\n \"artifact_materializer_source_revalidation_failed\",\n \"artifact_materializer_source_stream_identity_mismatch\",\n \"cleared_goal_live_publish_failed\",\n \"codex_failover_checkpoint_failed\",\n \"codex_fleet_shadow_failed\",\n \"codex_lease_loss_checkpoint_failed\",\n \"codex_active_credential_read_failed\",\n \"command_yield_timeout\",\n \"conflict\",\n \"control_wake_dispatch_failed\",\n \"fenced_event_live_publish_failed\",\n \"forbidden\",\n \"host_export_batch_delivery_failed\",\n \"host_export_failure_settlement_stale\",\n \"host_export_pump_iteration_failed\",\n \"host_export_retention_prune_failed\",\n \"idempotency_conflict\",\n \"incompatible_exposed_ports\",\n \"internal_error\",\n \"limit_exceeded\",\n \"mcp_close_failed\",\n \"mcp_connect_failed\",\n \"mcp_tool_call_failed\",\n \"mcp_tools_list_failed\",\n \"mcp_transport_failed\",\n \"memory_edit_embedding_failed\",\n \"memory_hybrid_vector_failed\",\n \"memory_save_embedding_failed\",\n \"nats_auth_callout_start_failed\",\n \"nested_agent_depth_exceeded\",\n \"nested_agent_depth_override_forbidden\",\n \"not_found\",\n \"oauth_operation_failed\",\n \"otlp_export_failed\",\n \"payment_required\",\n \"provider_verification_failed\",\n \"sandbox_channel_a_cancelled\",\n \"sandbox_channel_a_lifecycle_conflict\",\n \"sandbox_channel_a_operation_failed\",\n \"sandbox_channel_a_provider_busy\",\n \"sandbox_channel_a_provider_unavailable\",\n \"screenshot_capture_failed\",\n \"session_event_live_publish_failed\",\n \"session_workflow_wake_failed\",\n \"snapshot_operation_failed\",\n \"startup_dependency_retry\",\n \"tool_list_too_large\",\n \"tool_result_too_large\",\n \"codemode_operation_failed\",\n \"unauthenticated\",\n \"upstream_unavailable\",\n \"validation_failed\",\n \"worker_draining\",\n \"worker_operation_failed\",\n \"worker_shutdown_request_failed\",\n \"workspace_control_live_publish_failed\",\n]);\n\nconst PUBLIC_TELEMETRY_ERROR_ORIGINS = new Set([\n \"api\",\n \"core\",\n \"db\",\n \"events\",\n \"host-export\",\n \"oauth\",\n \"observability\",\n \"runtime\",\n \"sandbox-computer\",\n \"sandbox-resume\",\n \"codemode\",\n \"worker\",\n \"worker-lifecycle\",\n]);\n\nexport type SandboxOperationMetricObservation = {\n backend: string;\n op: string;\n outcome: \"ok\" | \"not_found\" | \"failed\";\n durationMs: number;\n};\n\nexport function createObservability(\n settings: ObservabilitySettings,\n options: ObservabilityOptions,\n): Observability {\n return new Observability(settings, options);\n}\n\ntype MetricRegistration = {\n kind: \"counter\" | \"gauge\" | \"histogram\";\n labelNames: string[];\n};\n\nexport class Observability {\n private readonly registry = new Registry();\n private readonly counters = new Map<string, Counter<string>>();\n private readonly gauges = new Map<string, Gauge<string>>();\n private readonly histograms = new Map<string, Histogram<string>>();\n private readonly registrations = new Map<string, MetricRegistration>();\n private readonly now: () => number;\n private readonly exporter: (\n url: string,\n body: unknown,\n headers: Record<string, string>,\n ) => Promise<void>;\n private readonly resourceAttributes: Attributes;\n\n constructor(\n private readonly settings: ObservabilitySettings,\n private readonly options: ObservabilityOptions,\n ) {\n this.now = options.now ?? Date.now;\n this.exporter = options.exporter ?? defaultExporter;\n this.resourceAttributes = {\n \"service.name\": settings.serviceName,\n \"deployment.environment\": settings.environment,\n \"opengeni.component\": options.component,\n };\n this.registry.setDefaultLabels({\n service: settings.serviceName,\n environment: settings.environment,\n component: options.component,\n deployment_revision: settings.deploymentRevision ?? \"dev\",\n });\n if (settings.observabilityMetricsEnabled) {\n collectDefaultMetrics({ register: this.registry, prefix: \"opengeni_\" });\n this.setGauge({\n name: \"opengeni_build_info\",\n help: \"OpenGeni build information.\",\n labels: {\n version: buildVersion(),\n revision: settings.deploymentRevision ?? \"dev\",\n },\n value: 1,\n });\n this.registerSandboxRolloutConfig();\n this.registerTenancyCompatibilityLanes();\n }\n }\n\n /**\n * Publish every compatibility lane at zero on startup. Without this an\n * un-exercised lane has no series at all, and an operator cannot tell \"this\n * lane is dormant\" from \"this lane was never wired up\" - the two readings\n * that matter most to a cutover gate.\n */\n private registerTenancyCompatibilityLanes(): void {\n for (const lane of TENANCY_COMPATIBILITY_LANES) {\n this.incrementCounter({ ...TENANCY_COMPATIBILITY_LANE_METRIC, labels: { lane }, amount: 0 });\n }\n }\n\n private registerSandboxRolloutConfig(): void {\n const ownership = this.settings.sandboxOwnershipEnabled;\n const lazyConfigured = this.settings.sandboxLazyProvisionEnabled;\n const rigVerification = this.settings.rigVerificationLeaseOwnershipEnabled;\n if (\n typeof ownership !== \"boolean\" ||\n typeof lazyConfigured !== \"boolean\" ||\n typeof rigVerification !== \"boolean\"\n ) {\n return;\n }\n\n const values = [\n [\"ownership\", \"configured\", ownership],\n [\"ownership\", \"effective\", ownership],\n [\"lazy_provision\", \"configured\", lazyConfigured],\n [\"lazy_provision\", \"effective\", ownership && lazyConfigured],\n [\"rig_verification_lease_ownership\", \"configured\", rigVerification],\n [\"rig_verification_lease_ownership\", \"effective\", rigVerification],\n ] as const;\n for (const [feature, state, enabled] of values) {\n this.setGauge({\n name: \"opengeni_sandbox_rollout_config\",\n help: \"Configured and effective sandbox rollout state for this workload revision.\",\n labels: { feature, state },\n value: enabled ? 1 : 0,\n });\n }\n }\n\n debug(message: string, attributes: Attributes = {}): void {\n this.log(\"debug\", message, attributes);\n }\n\n info(message: string, attributes: Attributes = {}): void {\n this.log(\"info\", message, attributes);\n }\n\n warn(message: string, attributes: Attributes = {}): void {\n this.log(\"warn\", message, attributes);\n }\n\n error(message: string, attributes: Attributes = {}): void {\n this.log(\"error\", message, attributes);\n }\n\n log(\n level: \"debug\" | \"info\" | \"warn\" | \"error\",\n message: string,\n attributes: Attributes = {},\n ): void {\n const publicAttributes = projectPublicTelemetryAttributes(attributes);\n if (!this.settings.observabilityStructuredLogs) {\n if (level === \"warn\") {\n console.warn(message);\n } else if (level === \"error\") {\n console.error(message);\n } else {\n console.log(message);\n }\n return;\n }\n const record = {\n timestamp: new Date(this.now()).toISOString(),\n level,\n message,\n service: this.settings.serviceName,\n environment: this.settings.environment,\n component: this.options.component,\n ...cleanAttributes(publicAttributes),\n };\n const serialized = JSON.stringify(record);\n if (level === \"warn\") {\n console.warn(serialized);\n } else if (level === \"error\") {\n console.error(serialized);\n } else {\n console.log(serialized);\n }\n }\n\n startSpan(name: string, attributes: Attributes = {}): Span {\n const traceId = randomHex(16);\n const spanId = randomHex(8);\n const startMs = this.now();\n let ended = false;\n return {\n traceId,\n spanId,\n end: (input = {}) => {\n if (ended) {\n return;\n }\n ended = true;\n const telemetryError =\n input.error !== undefined && input.error !== null\n ? projectSpanErrorForTelemetry(input.error)\n : undefined;\n const errorAttributes = telemetryError ? errorToAttributes(telemetryError) : {};\n this.exportSpan({\n traceId,\n spanId,\n name,\n startMs,\n endMs: this.now(),\n attributes: {\n ...projectPublicTelemetryAttributes({\n ...attributes,\n ...input.attributes,\n ...errorAttributes,\n }),\n },\n ...(telemetryError ? { error: telemetryError } : {}),\n });\n },\n };\n }\n\n recordHttpRequest(input: {\n method: string;\n route: string;\n status: number;\n durationSeconds: number;\n }): void {\n this.incrementCounter({\n name: \"opengeni_http_requests_total\",\n help: \"Total HTTP requests handled by OpenGeni.\",\n labels: {\n method: input.method,\n route: input.route,\n status: String(input.status),\n component: this.options.component,\n },\n });\n this.observeHistogram({\n name: \"opengeni_http_request_duration_seconds\",\n help: \"HTTP request duration in seconds.\",\n buckets: httpHistogramBuckets,\n value: input.durationSeconds,\n labels: {\n method: input.method,\n route: input.route,\n component: this.options.component,\n },\n });\n }\n\n recordWorkerActivity(input: { activity: string; status: string; durationSeconds: number }): void {\n this.incrementCounter({\n name: \"opengeni_worker_activity_runs_total\",\n help: \"Total worker activity executions.\",\n labels: {\n activity: input.activity,\n status: input.status,\n component: this.options.component,\n },\n });\n this.observeHistogram({\n name: \"opengeni_worker_activity_duration_seconds\",\n help: \"Worker activity duration in seconds.\",\n buckets: durationHistogramBuckets,\n value: input.durationSeconds,\n labels: {\n activity: input.activity,\n component: this.options.component,\n },\n });\n }\n\n incrementCounter(input: {\n name: string;\n help?: string;\n labels?: MetricLabels;\n amount?: number;\n }): void {\n if (!this.settings.observabilityMetricsEnabled) {\n return;\n }\n const labels = normalizeLabels(input.labels);\n const counter = this.counter(\n input.name,\n input.help ?? `${input.name} counter.`,\n Object.keys(labels),\n );\n counter.inc(labels as never, input.amount ?? 1);\n }\n\n setGauge(input: { name: string; help?: string; labels?: MetricLabels; value: number }): void {\n if (!this.settings.observabilityMetricsEnabled) {\n return;\n }\n const labels = normalizeLabels(input.labels);\n const gauge = this.gauge(input.name, input.help ?? `${input.name} gauge.`, Object.keys(labels));\n gauge.set(labels as never, input.value);\n }\n\n incrementGauge(input: {\n name: string;\n help?: string;\n labels?: MetricLabels;\n amount?: number;\n }): void {\n if (!this.settings.observabilityMetricsEnabled) {\n return;\n }\n const labels = normalizeLabels(input.labels);\n const gauge = this.gauge(input.name, input.help ?? `${input.name} gauge.`, Object.keys(labels));\n gauge.inc(labels as never, input.amount ?? 1);\n }\n\n observeHistogram(input: {\n name: string;\n help?: string;\n labels?: MetricLabels;\n value: number;\n buckets?: number[];\n }): void {\n if (!this.settings.observabilityMetricsEnabled) {\n return;\n }\n const labels = normalizeLabels(input.labels);\n const histogram = this.histogram(\n input.name,\n input.help ?? `${input.name} histogram.`,\n Object.keys(labels),\n input.buckets ?? durationHistogramBuckets,\n );\n histogram.observe(labels as never, input.value);\n }\n\n async prometheusMetrics(): Promise<string> {\n if (!this.settings.observabilityMetricsEnabled) {\n return \"\";\n }\n return await this.registry.metrics();\n }\n\n private counter(name: string, help: string, labelNames: string[]): Counter<string> {\n const existing = this.counters.get(name);\n if (existing) {\n this.assertRegistration(name, \"counter\", labelNames);\n return existing;\n }\n this.register(name, \"counter\", labelNames);\n const metric = new Counter({ name, help, labelNames, registers: [this.registry] });\n this.counters.set(name, metric);\n return metric;\n }\n\n private gauge(name: string, help: string, labelNames: string[]): Gauge<string> {\n const existing = this.gauges.get(name);\n if (existing) {\n this.assertRegistration(name, \"gauge\", labelNames);\n return existing;\n }\n this.register(name, \"gauge\", labelNames);\n const metric = new Gauge({ name, help, labelNames, registers: [this.registry] });\n this.gauges.set(name, metric);\n return metric;\n }\n\n private histogram(\n name: string,\n help: string,\n labelNames: string[],\n buckets: number[],\n ): Histogram<string> {\n const existing = this.histograms.get(name);\n if (existing) {\n this.assertRegistration(name, \"histogram\", labelNames);\n return existing;\n }\n this.register(name, \"histogram\", labelNames);\n const metric = new Histogram({ name, help, labelNames, buckets, registers: [this.registry] });\n this.histograms.set(name, metric);\n return metric;\n }\n\n private register(name: string, kind: MetricRegistration[\"kind\"], labelNames: string[]): void {\n const sorted = [...labelNames].sort();\n this.registrations.set(name, { kind, labelNames: sorted });\n }\n\n private assertRegistration(\n name: string,\n kind: MetricRegistration[\"kind\"],\n labelNames: string[],\n ): void {\n const registration = this.registrations.get(name);\n const sorted = [...labelNames].sort();\n if (\n !registration ||\n registration.kind !== kind ||\n registration.labelNames.length !== sorted.length ||\n registration.labelNames.some((label, index) => label !== sorted[index])\n ) {\n throw new Error(\n `Metric ${name} was already registered as ${registration?.kind ?? \"unknown\"} ` +\n `with labels [${registration?.labelNames.join(\",\") ?? \"\"}], not ${kind} [${sorted.join(\",\")}]`,\n );\n }\n }\n\n private exportSpan(span: {\n traceId: string;\n spanId: string;\n name: string;\n startMs: number;\n endMs: number;\n attributes: Attributes;\n error?: TelemetrySpanError;\n }): void {\n if (!this.settings.observabilityOtlpEndpoint) {\n return;\n }\n const endpoint = `${this.settings.observabilityOtlpEndpoint.replace(/\\/$/, \"\")}/v1/traces`;\n const body = {\n resourceSpans: [\n {\n resource: {\n attributes: otlpAttributes(this.resourceAttributes),\n },\n scopeSpans: [\n {\n scope: {\n name: \"@opengeni/observability\",\n version: \"0.1.0\",\n },\n spans: [\n {\n traceId: span.traceId,\n spanId: span.spanId,\n name: span.name,\n kind: 1,\n startTimeUnixNano: millisToNanos(span.startMs),\n endTimeUnixNano: millisToNanos(span.endMs),\n attributes: otlpAttributes(span.attributes),\n status: span.error ? { code: 2, message: span.error.statusMessage } : { code: 1 },\n },\n ],\n },\n ],\n },\n ],\n };\n void this.exporter(endpoint, body, parseHeaders(this.settings.observabilityOtlpHeaders)).catch(\n () => {\n this.warn(\"OTLP span export failed\", {\n errorClass: \"TelemetryExportError\",\n errorCode: \"otlp_export_failed\",\n origin: \"observability\",\n });\n },\n );\n }\n}\n\n/**\n * Convert routed sandbox-provider observations into one bounded Prometheus\n * contract shared by API-direct and worker-turn execution. Provider/session\n * identifiers, commands, paths, and other request data can never become labels:\n * a future backend or operation is deliberately collapsed to `unknown` until\n * this allowlist is reviewed.\n *\n * The returned callback is fail-safe. Metrics must never change the provider\n * operation's result; a registration/exporter error is counted best-effort and\n * then swallowed at this telemetry boundary.\n */\nexport function sandboxOperationMetricObserver(\n observability: Observability,\n): (observation: SandboxOperationMetricObservation) => void {\n return (observation) => {\n const backend = SANDBOX_OPERATION_BACKENDS.has(observation.backend)\n ? observation.backend\n : \"unknown\";\n const op = SANDBOX_OPERATION_NAMES.has(observation.op) ? observation.op : \"unknown\";\n try {\n observability.incrementCounter({\n name: \"opengeni_sandbox_operations_total\",\n help: \"Physical routed sandbox provider operations by backend, operation, and outcome.\",\n labels: { backend, op, outcome: observation.outcome },\n });\n observability.observeHistogram({\n name: \"opengeni_sandbox_operation_duration_seconds\",\n help: \"Physical routed sandbox provider-operation duration in seconds.\",\n labels: { backend, op },\n value: Math.max(0, observation.durationMs) / 1_000,\n });\n } catch {\n try {\n observability.incrementCounter({\n name: \"opengeni_observability_observer_errors_total\",\n help: \"Observability observer failures isolated from product execution.\",\n labels: { observer: \"sandbox_operation\" },\n });\n } catch {\n // The metrics registry itself is unhealthy. Product execution remains\n // authoritative and must not inherit an observability failure.\n }\n }\n };\n}\n\nexport type InteractionOperationMetricObservation = {\n resource: string;\n operation: string;\n outcome: string;\n mode: string;\n durationMs: number;\n replayed?: boolean | undefined;\n};\n\n/** Safe low-cardinality telemetry for Browser/Computer control operations.\n * Resource ids, URLs, locators, page/app text, and input values are excluded by\n * construction. Unknown future enum values collapse until explicitly reviewed. */\nexport function interactionOperationMetricObserver(\n observability: Observability | null | undefined,\n): (observation: InteractionOperationMetricObservation) => void {\n if (!observability) return () => undefined;\n return (observation) => {\n if (observation.replayed) return;\n const resource = boundedMetricEnum(INTERACTION_RESOURCES, observation.resource);\n const operation = boundedMetricEnum(INTERACTION_OPERATIONS, observation.operation);\n const outcome = boundedMetricEnum(INTERACTION_OUTCOMES, observation.outcome);\n const mode = boundedMetricEnum(INTERACTION_MODES, observation.mode);\n try {\n observability.incrementCounter({\n name: \"opengeni_interaction_operations_total\",\n help: \"Browser and Computer operations by bounded resource, operation, mode, and outcome.\",\n labels: { resource, operation, mode, outcome },\n });\n observability.observeHistogram({\n name: \"opengeni_interaction_operation_duration_seconds\",\n help: \"Browser and Computer operation duration in seconds.\",\n labels: { resource, operation, mode },\n value: boundedMetricDuration(observation.durationMs),\n });\n } catch {\n recordObserverFailure(observability, \"interaction_operation\");\n }\n };\n}\n\nexport type InteractionAuthMetricObservation = {\n state: string;\n durationMs: number;\n replayed?: boolean | undefined;\n};\n\nexport function interactionAuthMetricObserver(\n observability: Observability | null | undefined,\n): (observation: InteractionAuthMetricObservation) => void {\n if (!observability) return () => undefined;\n return (observation) => {\n if (observation.replayed) return;\n const state = boundedMetricEnum(INTERACTION_AUTH_STATES, observation.state);\n try {\n observability.incrementCounter({\n name: \"opengeni_interaction_auth_transitions_total\",\n help: \"Browser authentication transitions by bounded resulting state.\",\n labels: { state },\n });\n observability.observeHistogram({\n name: \"opengeni_interaction_auth_transition_duration_seconds\",\n help: \"Browser authentication transition request duration in seconds.\",\n labels: { state },\n value: boundedMetricDuration(observation.durationMs),\n });\n } catch {\n recordObserverFailure(observability, \"interaction_auth\");\n }\n };\n}\n\nexport type InteractionInterventionMetricObservation = {\n kind: string;\n outcome: string;\n waitMs?: number | undefined;\n replayed?: boolean | undefined;\n};\n\nexport function interactionInterventionMetricObserver(\n observability: Observability | null | undefined,\n): (observation: InteractionInterventionMetricObservation) => void {\n if (!observability) return () => undefined;\n return (observation) => {\n if (observation.replayed) return;\n const kind = boundedMetricEnum(INTERACTION_INTERVENTION_KINDS, observation.kind);\n const outcome = boundedMetricEnum(INTERACTION_INTERVENTION_OUTCOMES, observation.outcome);\n try {\n observability.incrementCounter({\n name: \"opengeni_interaction_interventions_total\",\n help: \"Human browser/computer interventions by bounded kind and outcome.\",\n labels: { kind, outcome },\n });\n if (observation.waitMs !== undefined) {\n observability.observeHistogram({\n name: \"opengeni_interaction_intervention_wait_seconds\",\n help: \"Time an interaction intervention remained open before settlement.\",\n labels: { kind, outcome },\n value: boundedMetricDuration(observation.waitMs),\n });\n }\n } catch {\n recordObserverFailure(observability, \"interaction_intervention\");\n }\n };\n}\n\nexport type WorkspaceInsightsMetricObservation = {\n range: string;\n providerFiltered: boolean;\n modelFiltered: boolean;\n outcome: string;\n durationMs: number;\n};\n\n/**\n * Identity-free route timing for Workspace Insights. The dedicated two-second\n * bucket is the service target; fixed enums and filter-presence flags keep\n * tenant ids and caller-supplied provider/model values out of telemetry.\n */\nexport function workspaceInsightsMetricObserver(\n observability: Observability | null | undefined,\n): (observation: WorkspaceInsightsMetricObservation) => void {\n if (!observability) return () => undefined;\n return (observation) => {\n const range = boundedMetricEnum(WORKSPACE_INSIGHTS_RANGES, observation.range);\n const outcome = boundedMetricEnum(WORKSPACE_INSIGHTS_OUTCOMES, observation.outcome);\n const providerFilter = observation.providerFiltered ? \"filtered\" : \"all\";\n const modelFilter = observation.modelFiltered ? \"filtered\" : \"all\";\n const durationSeconds = boundedMetricDuration(observation.durationMs);\n try {\n observability.observeHistogram({\n name: \"opengeni_workspace_insights_request_duration_seconds\",\n help: \"Workspace Insights route service duration by bounded range, filter presence, and outcome.\",\n buckets: workspaceInsightsDurationHistogramBuckets,\n labels: {\n range,\n provider_filter: providerFilter,\n model_filter: modelFilter,\n outcome,\n },\n value: durationSeconds,\n });\n observability.info(\"Workspace Insights request measured\", {\n surface: \"workspace_insights\",\n eventType: \"request_latency\",\n route: \"/v1/workspaces/:workspaceId/insights\",\n outcome,\n durationMs: Math.round(durationSeconds * 1_000),\n });\n } catch {\n recordObserverFailure(observability, \"workspace_insights\");\n }\n };\n}\n\nfunction boundedMetricEnum(allowed: ReadonlySet<string>, value: string): string {\n return allowed.has(value) ? value : \"unknown\";\n}\n\nfunction boundedMetricDuration(durationMs: number): number {\n return Number.isFinite(durationMs) ? Math.max(0, durationMs) / 1_000 : 0;\n}\n\nfunction recordObserverFailure(observability: Observability, observer: string): void {\n try {\n observability.incrementCounter({\n name: \"opengeni_observability_observer_errors_total\",\n help: \"Observability observer failures isolated from product execution.\",\n labels: { observer },\n });\n } catch {\n // The metrics registry itself is unhealthy. Product execution remains\n // authoritative and must not inherit an observability failure.\n }\n}\n\nexport type StartupDependencyRetryEvent = {\n label: string;\n attempt: number;\n attempts: number;\n delayMs: number;\n error: unknown;\n};\n\nexport function logStartupDependencyRetry(\n observability: Observability,\n event: StartupDependencyRetryEvent,\n): void {\n const dependency = PUBLIC_STARTUP_DEPENDENCIES.has(event.label) ? event.label : \"Dependency\";\n observability.warn(\n `Startup dependency ${dependency} connection failed; retrying (${event.attempt}/${event.attempts} in ${event.delayMs}ms)`,\n {\n dependency,\n attempt: event.attempt,\n attempts: event.attempts,\n delayMs: event.delayMs,\n errorClass: \"StartupDependencyError\",\n errorCode: \"startup_dependency_retry\",\n origin: \"observability\",\n },\n );\n}\n\nfunction normalizeLabels(labels: MetricLabels = {}): Record<string, string> {\n return Object.fromEntries(\n Object.entries(labels)\n .filter(([, value]) => value !== undefined && value !== null)\n .map(([key, value]): [string, string] => [key, String(value)])\n .sort((left, right) => left[0].localeCompare(right[0])),\n );\n}\n\nfunction buildVersion(): string {\n return process.env.OPENGENI_VERSION ?? process.env.npm_package_version ?? \"dev\";\n}\n\nfunction cleanAttributes(attributes: Attributes): Record<string, string | number | boolean | null> {\n return Object.fromEntries(\n Object.entries(attributes).filter(([, value]) => value !== undefined),\n ) as Record<string, string | number | boolean | null>;\n}\n\nfunction projectPublicTelemetryAttributes(attributes: Attributes): Attributes {\n if (\"errorClass\" in attributes || \"errorCode\" in attributes) {\n return {\n ...projectStartupDependencyAttributes(attributes),\n ...projectPublicChannelADiagnosticAttributes(attributes),\n ...projectPublicDiagnosticAttributes(attributes),\n };\n }\n return Object.fromEntries(\n Object.entries(attributes).filter(([key, value]) => {\n if (value === undefined) return false;\n if (PUBLIC_TELEMETRY_ATTRIBUTE_KEYS.has(key)) return true;\n const pattern = PUBLIC_TELEMETRY_OPAQUE_ATTRIBUTE_PATTERNS.get(key);\n return typeof value === \"string\" && pattern?.test(value) === true;\n }),\n );\n}\n\nfunction projectStartupDependencyAttributes(attributes: Attributes): Attributes {\n if (\n attributes.errorClass !== \"StartupDependencyError\" ||\n attributes.errorCode !== \"startup_dependency_retry\"\n ) {\n return {};\n }\n const dependency = attributes.dependency;\n const attempt = attributes.attempt;\n const attempts = attributes.attempts;\n const delayMs = attributes.delayMs;\n return {\n ...(typeof dependency === \"string\" && PUBLIC_STARTUP_DEPENDENCIES.has(dependency)\n ? { dependency }\n : {}),\n ...(typeof attempt === \"number\" && Number.isInteger(attempt) && attempt > 0 ? { attempt } : {}),\n ...(typeof attempts === \"number\" && Number.isInteger(attempts) && attempts > 0\n ? { attempts }\n : {}),\n ...(typeof delayMs === \"number\" && Number.isFinite(delayMs) && delayMs >= 0 ? { delayMs } : {}),\n };\n}\n\nfunction projectPublicChannelADiagnosticAttributes(attributes: Attributes): Attributes {\n if (attributes.errorClass !== \"SandboxChannelAOperationError\") return {};\n const backend = attributes.backend;\n const op = attributes.op;\n const outcome = attributes.outcome;\n const reason = attributes.reason;\n const durationMs = attributes.durationMs;\n const sandboxLeaseKey = attributes.sandboxLeaseKey;\n return {\n ...(typeof backend === \"string\" && SANDBOX_OPERATION_BACKENDS.has(backend) ? { backend } : {}),\n ...(typeof op === \"string\" && PUBLIC_CHANNEL_A_OPERATIONS.has(op) ? { op } : {}),\n ...(outcome === \"failed\" ? { outcome } : {}),\n ...(typeof reason === \"string\" && PUBLIC_CHANNEL_A_FAILURE_REASONS.has(reason)\n ? { reason }\n : {}),\n ...(typeof durationMs === \"number\" && Number.isFinite(durationMs) && durationMs >= 0\n ? { durationMs }\n : {}),\n ...(typeof sandboxLeaseKey === \"string\" &&\n PUBLIC_TELEMETRY_OPAQUE_ATTRIBUTE_PATTERNS.get(\"sandboxLeaseKey\")?.test(sandboxLeaseKey)\n ? { sandboxLeaseKey }\n : {}),\n };\n}\n\nfunction projectPublicDiagnosticAttributes(attributes: Attributes): Attributes {\n const errorClass = attributes.errorClass;\n const errorCode = attributes.errorCode;\n const status = attributes.status;\n const origin = attributes.origin;\n const correlationId = attributes.correlationId;\n return {\n errorClass:\n typeof errorClass === \"string\" && PUBLIC_TELEMETRY_ERROR_CLASSES.has(errorClass)\n ? errorClass\n : \"OperationError\",\n ...(typeof errorCode === \"string\" && PUBLIC_TELEMETRY_ERROR_CODES.has(errorCode)\n ? { errorCode }\n : {}),\n ...(typeof status === \"number\" && Number.isInteger(status) && status >= 100 && status <= 599\n ? { status }\n : {}),\n ...(typeof origin === \"string\" && PUBLIC_TELEMETRY_ERROR_ORIGINS.has(origin) ? { origin } : {}),\n ...(typeof correlationId === \"string\" &&\n PUBLIC_TELEMETRY_OPAQUE_ATTRIBUTE_PATTERNS.get(\"correlationId\")?.test(correlationId)\n ? { correlationId }\n : {}),\n };\n}\n\ntype TelemetrySpanError = {\n type: string;\n statusCode?: number;\n statusMessage: string;\n};\n\n/**\n * External OTLP projection. It intentionally exports only error class/status\n * metadata and never mutates canonical OpenGeni errors, events, or history.\n */\nfunction projectSpanErrorForTelemetry(error: unknown): TelemetrySpanError {\n const statusCode = errorStatusCode(error);\n return {\n type: \"OperationError\",\n ...(statusCode === undefined ? {} : { statusCode }),\n statusMessage: statusCode === undefined ? \"operation failed\" : `HTTP ${statusCode}`,\n };\n}\n\nfunction errorStatusCode(error: unknown): number | undefined {\n if (typeof error !== \"object\" || error === null) return undefined;\n try {\n const value = (error as { status?: unknown; statusCode?: unknown }).status;\n const statusCode =\n Number.isInteger(value) && typeof value === \"number\"\n ? value\n : (error as { statusCode?: unknown }).statusCode;\n return Number.isInteger(statusCode) &&\n typeof statusCode === \"number\" &&\n statusCode >= 100 &&\n statusCode <= 599\n ? statusCode\n : undefined;\n } catch {\n // OTLP projection must never mask the exact internal failure.\n return undefined;\n }\n}\n\nfunction errorToAttributes(error: TelemetrySpanError): Attributes {\n return {\n \"error.type\": error.type,\n ...(error.statusCode === undefined ? {} : { \"error.status_code\": error.statusCode }),\n };\n}\n\nfunction otlpAttributes(\n attributes: Attributes,\n): Array<{ key: string; value: Record<string, string | number | boolean> }> {\n return Object.entries(cleanAttributes(attributes)).map(([key, value]) => ({\n key,\n value: otlpValue(value),\n }));\n}\n\nfunction otlpValue(\n value: string | number | boolean | null,\n): Record<string, string | number | boolean> {\n if (typeof value === \"number\") {\n return Number.isInteger(value) ? { intValue: value } : { doubleValue: value };\n }\n if (typeof value === \"boolean\") {\n return { boolValue: value };\n }\n return { stringValue: value === null ? \"\" : boundedOtlpString(value) };\n}\n\nfunction boundedOtlpString(value: string): string {\n const bytes = new TextEncoder().encode(value);\n if (bytes.byteLength <= 512) return value;\n return `${new TextDecoder().decode(bytes.slice(0, 509))}…`;\n}\n\nfunction millisToNanos(ms: number): string {\n return String(BigInt(Math.round(ms)) * 1_000_000n);\n}\n\nfunction randomHex(bytes: number): string {\n const values = crypto.getRandomValues(new Uint8Array(bytes));\n return Array.from(values, (value) => value.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\nexport function parseHeaders(value: string): Record<string, string> {\n if (!value.trim()) {\n return {};\n }\n const entries: Array<[string, string]> = value\n .split(\",\")\n .map((pair): [string, string] => {\n const separator = pair.indexOf(\"=\");\n if (separator === -1) {\n return [pair.trim(), \"\"];\n }\n return [pair.slice(0, separator).trim(), pair.slice(separator + 1).trim()];\n })\n .filter(([key]) => key.length > 0);\n return Object.fromEntries(entries);\n}\n\nasync function defaultExporter(\n url: string,\n body: unknown,\n headers: Record<string, string>,\n): Promise<void> {\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n ...headers,\n },\n body: JSON.stringify(body),\n });\n if (!response.ok) {\n throw new Error(`OTLP endpoint returned HTTP ${response.status}`);\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { collectDefaultMetrics, Counter, Gauge, Histogram, Registry } from \"prom-client\";\nimport { SandboxBackend } from \"@opengeni/contracts\";\n\nexport type AttributeValue = string | number | boolean | null | undefined;\nexport type Attributes = Record<string, AttributeValue>;\n\nexport type ObservabilitySettings = {\n serviceName: string;\n environment: string;\n deploymentRevision?: string | undefined;\n observabilityStructuredLogs: boolean;\n observabilityMetricsEnabled: boolean;\n observabilityOtlpEndpoint?: string | undefined;\n observabilityOtlpHeaders: string;\n sandboxOwnershipEnabled?: boolean | undefined;\n sandboxLazyProvisionEnabled?: boolean | undefined;\n rigVerificationLeaseOwnershipEnabled?: boolean | undefined;\n};\n\nexport type ObservabilityOptions = {\n component: string;\n now?: () => number;\n exporter?: (url: string, body: unknown, headers: Record<string, string>) => Promise<void>;\n};\n\nexport type Span = {\n traceId: string;\n spanId: string;\n end: (input?: { attributes?: Attributes; error?: unknown }) => void;\n};\n\nexport type MetricLabels = Record<string, AttributeValue>;\n\n/**\n * Stable, non-reversible correlation key for one logical sandbox lease. Public\n * telemetry intentionally drops workspace/group identifiers; this key lets an\n * operator correlate API, worker, and reaper failures without publishing\n * either UUID. The domain separator prevents reuse as a generic identifier\n * digest.\n */\nexport function sandboxLeaseTelemetryKey(workspaceId: string, sandboxGroupId: string): string {\n return `slk_${createHash(\"sha256\")\n .update(\"opengeni:sandbox-lease-telemetry:v1\\0\")\n .update(workspaceId)\n .update(\"\\0\")\n .update(sandboxGroupId)\n .digest(\"hex\")\n .slice(0, 32)}`;\n}\n\n/**\n * Stable selectors shared by OpenGeni's runtime metrics and optional\n * Prometheus/Grafana distribution. Operators can use these values for custom\n * namespaces and dashboard ConfigMaps without duplicating chart internals.\n */\nexport const OPENGENI_OBSERVABILITY_DISTRIBUTION = {\n monitoringNamespaceLabel: \"opengeni.ai/monitoring\",\n monitoringNamespaceLabelValue: \"enabled\",\n grafanaDashboardLabel: \"grafana_dashboard\",\n grafanaDashboardLabelValue: \"1\",\n} as const;\n\nconst httpHistogramBuckets = [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10];\nconst durationHistogramBuckets = [\n 0.01, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10, 30, 60, 120, 300, 900, 1800, 3600,\n];\n\nconst SANDBOX_OPERATION_BACKENDS = new Set<string>([...SandboxBackend.options, \"unprovisioned\"]);\n\nconst SANDBOX_OPERATION_NAMES = new Set([\n \"desktopInput\",\n \"screenshot\",\n \"exec\",\n \"execCommand\",\n \"writeStdin\",\n \"cancelExecCommand\",\n \"readFile\",\n \"writeFile\",\n \"listDir\",\n \"pathExists\",\n \"viewImage\",\n \"materializeEntry\",\n \"editor.createFile\",\n \"editor.updateFile\",\n \"editor.deleteFile\",\n \"resolveExposedPort\",\n \"serializeSessionState\",\n]);\n\n/**\n * Closed set of organization-tenancy compatibility lanes (the tenancy\n * migration's validate phase; see `docs/organization-tenancy.md`).\n *\n * Each entry names one legacy behaviour a live request can still take today.\n * The metric built from them is deliberately a COUNTER of lane USES, and it\n * measures exactly one thing: **is this lane still being exercised?** That is\n * the question the tenancy cutover gate (\"zero incompatible writers\") actually\n * asks, and it is answerable.\n *\n * It is emphatically NOT a burndown of unmigrated rows, and must never be\n * relabelled as one. Every one of these lanes is still *open*: the live write\n * paths keep producing rows in it, so no row-count predicate over any of them\n * can reach zero and a backlog gauge would read as a permanent, untruthful\n * unmigrated backlog. `docs/organization-tenancy.md` records, per lane, why -\n * including the lanes deliberately left uninstrumented because no truthful\n * signal exists for them yet.\n *\n * The recorded value is the lane name and nothing else. No organization,\n * workspace, session, subject, connection, or resource identity, and no\n * credential, name, or content, may ever become a label here.\n */\nexport const TENANCY_COMPATIBILITY_LANES = [\n /**\n * A provider connection carrying `authority_scope = 'legacy_user'` was\n * resolved for accepted use: a personal row with no common authority or\n * grant, admitted through `legacy_user_compatibility` provenance instead of\n * an explicit delegation. Migration 0256 backfilled the existing rows, but\n * its `bind_connection_authority` trigger still classifies a NEW personal\n * connection this way whenever the inserting subject has no active\n * organization membership, so this counter is expected to stay above zero\n * until that classification changes. That is the finding, not a defect.\n */\n \"connection_legacy_user\",\n /**\n * A workspace-scope connection ref carried no connection id, so the\n * accepted-use authority (migration 0279) could not identify the exact row\n * and the request fell back to the unprivileged pre-snapshot resolution.\n * This lane writes no `connection_use_audit_facts` row and leaves no durable\n * trace of any kind, so a use counter is the only possible evidence it was\n * taken at all.\n */\n \"connection_pre_snapshot_ref\",\n /**\n * A NEW persistable `/workspace` mutation was refused because the writer\n * behind it has no recorded authority (`authority_unattributed`): either a\n * direct request whose principal froze the pre-0096 legacy initiator, or a\n * retained process whose pre-0277 row has no tenancy half. This counts\n * REFUSED MUTATIONS, not unattributed rows - the turn and process admission\n * lanes deliberately still accept a `legacy_unattributed` initiator, and\n * nothing may invent the missing authority or disturb the running provider\n * process.\n */\n \"workspace_writer_unattributed\",\n] as const;\nexport type TenancyCompatibilityLane = (typeof TENANCY_COMPATIBILITY_LANES)[number];\n\nconst TENANCY_COMPATIBILITY_LANE_SET = new Set<string>(TENANCY_COMPATIBILITY_LANES);\n\nconst TENANCY_COMPATIBILITY_LANE_METRIC = {\n name: \"opengeni_tenancy_compatibility_lane_uses_total\",\n help: \"Live uses of an organization-tenancy compatibility lane, by lane.\",\n} as const;\n\n/**\n * Record one live use of a tenancy compatibility lane. Fail-safe by\n * construction: telemetry must never change an authorization or credential\n * outcome, so a registry failure is counted best-effort and swallowed here.\n */\nexport function recordTenancyCompatibilityLaneUse(\n observability: Observability | null | undefined,\n lane: TenancyCompatibilityLane,\n): void {\n if (!observability) return;\n // An unreviewed lane name must not silently mint a new series.\n if (!TENANCY_COMPATIBILITY_LANE_SET.has(lane)) return;\n try {\n observability.incrementCounter({ ...TENANCY_COMPATIBILITY_LANE_METRIC, labels: { lane } });\n } catch {\n recordObserverFailure(observability, \"tenancy_compatibility_lane\");\n }\n}\n\nconst INTERACTION_RESOURCES = new Set([\"browser\", \"computer\"]);\nconst INTERACTION_OPERATIONS = new Set([\n \"create\",\n \"end\",\n \"suspend\",\n \"resume\",\n \"publish\",\n \"observe\",\n \"act\",\n \"open_target\",\n \"select_target\",\n \"close_target\",\n \"attach\",\n \"auth_start\",\n \"auth_report\",\n \"auth_fill\",\n \"auth_verify\",\n \"intervention_create\",\n \"intervention_resolve\",\n]);\nconst INTERACTION_OUTCOMES = new Set([\n \"prepared\",\n \"dispatched\",\n \"completed\",\n \"failed\",\n \"outcome_unknown\",\n \"stale\",\n \"cancelled\",\n]);\nconst INTERACTION_MODES = new Set([\n \"semantic\",\n \"coordinate\",\n \"keyboard\",\n \"clipboard\",\n \"permission\",\n \"lifecycle\",\n \"media\",\n \"auth\",\n \"human\",\n]);\nconst INTERACTION_AUTH_STATES = new Set([\n \"discovering\",\n \"awaiting_choice\",\n \"awaiting_secret\",\n \"awaiting_external_action\",\n \"working\",\n \"verified\",\n \"failed\",\n \"cancelled\",\n]);\nconst INTERACTION_INTERVENTION_KINDS = new Set([\n \"manual_login\",\n \"mfa\",\n \"external_action\",\n \"confirmation\",\n \"other\",\n]);\nconst INTERACTION_INTERVENTION_OUTCOMES = new Set([\n \"opened\",\n \"completed\",\n \"dismissed\",\n \"expired\",\n \"cancelled\",\n]);\nconst WORKSPACE_INSIGHTS_RANGES = new Set([\"today\", \"week\", \"month\", \"ytd\"]);\nconst WORKSPACE_INSIGHTS_OUTCOMES = new Set([\"completed\", \"failed\"]);\nconst workspaceInsightsDurationHistogramBuckets = [0.05, 0.1, 0.25, 0.5, 1, 1.5, 2, 3, 5, 10, 30];\nconst PUBLIC_STARTUP_DEPENDENCIES = new Set([\n \"Modal private-registry image\",\n \"NATS\",\n \"PostgreSQL runtime posture\",\n \"Temporal\",\n \"Temporal client\",\n \"Temporal schedule (file upload reaper)\",\n \"Temporal schedule (sandbox reaper)\",\n \"Temporal schedule (session-workflow wake dispatcher)\",\n \"Temporal schedule (site auth maintenance)\",\n]);\n\n/**\n * External logs and OTLP are public/third-party projections, not canonical\n * OpenGeni storage. Only this reviewed closed set of operational fields may\n * cross that boundary. Unknown keys are omitted regardless of their value, so\n * a new diagnostic, identifier, command, response, or provider field cannot\n * become public by accident. This is schema projection, never value inspection\n * or rewriting.\n */\nconst PUBLIC_TELEMETRY_ATTRIBUTE_KEYS = new Set([\n \"http.request.method\",\n \"http.response.status_code\",\n \"opengeni.route\",\n \"opengeni.duration_ms\",\n \"opengeni.finalization_duration_ms\",\n \"opengeni.trigger_kind\",\n \"opengeni.status\",\n \"error.type\",\n \"error.status_code\",\n \"method\",\n \"route\",\n \"status\",\n \"durationMs\",\n \"attempt\",\n \"attempts\",\n \"delayMs\",\n \"provider\",\n \"providerApi\",\n \"model\",\n \"inputTokens\",\n \"outputTokens\",\n \"cachedTokens\",\n \"cacheWriteTokens\",\n \"reasoningTokens\",\n \"accountChangedFromPrevCall\",\n \"rejectedFields\",\n \"dependency\",\n \"activity\",\n \"backend\",\n \"op\",\n \"outcome\",\n \"eventType\",\n \"surface\",\n \"reason\",\n \"originalBytes\",\n \"deliveredBytes\",\n \"estimatedOriginalTokens\",\n \"estimatedDeliveredTokens\",\n \"fullEvidenceAvailable\",\n \"retainedOutputKind\",\n]);\n\n/** Opaque correlation fields require both a reviewed name and a closed value\n * grammar. Merely adding one to the ordinary allow-list would let an unrelated\n * caller accidentally publish a raw identifier under that name. */\nconst PUBLIC_TELEMETRY_OPAQUE_ATTRIBUTE_PATTERNS = new Map<string, RegExp>([\n [\"sandboxLeaseKey\", /^slk_[0-9a-f]{32}$/],\n [\"correlationId\", /^[A-Za-z0-9._:-]{1,128}$/],\n]);\n\nconst PUBLIC_CHANNEL_A_OPERATIONS = new Set([\n \"fs.list\",\n \"fs.list-batch\",\n \"fs.read\",\n \"fs.write\",\n \"fs.delete\",\n \"fs.move\",\n \"fs.mkdir\",\n \"git.status\",\n \"git.diff\",\n \"git.read-batch\",\n \"git.log\",\n \"git.show\",\n \"terminal.exec\",\n \"terminal.pty.open\",\n \"terminal.pty.write\",\n \"terminal.pty.resize\",\n \"terminal.pty.close\",\n \"read\",\n \"mutation\",\n]);\n\nconst PUBLIC_CHANNEL_A_FAILURE_REASONS = new Set([\n \"request_cancelled\",\n \"provider_read_busy\",\n \"provider_unavailable\",\n \"lifecycle_conflict\",\n \"request_rejected\",\n \"unexpected\",\n]);\n\nconst PUBLIC_API_FATAL_PHASES = new Set([\"startup\", \"running\"]);\nconst PUBLIC_API_FATAL_REASON_KINDS = new Set([\n \"bigint\",\n \"boolean\",\n \"error\",\n \"function\",\n \"null\",\n \"number\",\n \"object\",\n \"string\",\n \"symbol\",\n \"undefined\",\n]);\n\n/**\n * Public diagnostic values are protocol constants, never values inferred from\n * an exception's name, constructor, code, message, or enumerable properties.\n * Unknown classes collapse to one fixed fallback; unknown codes and origins\n * are omitted rather than copied through based on syntax.\n */\nconst PUBLIC_TELEMETRY_ERROR_CLASSES = new Set([\n \"ApiFatalOperationError\",\n \"OperationError\",\n \"CodexCheckpointOperationError\",\n \"CodexFleetShadowOperationError\",\n \"ComputerActionTimeoutError\",\n \"ComputerUnavailableError\",\n \"CredentialRenewalOperationError\",\n \"CredentialReadOperationError\",\n \"EventPublishOperationError\",\n \"GitCredentialRenewalOperationError\",\n \"HostExportOperationError\",\n \"HttpOperationError\",\n \"McpLifecycleError\",\n \"McpOperationError\",\n \"MemoryEmbeddingOperationError\",\n \"MemorySearchOperationError\",\n \"NatsAuthCalloutOperationError\",\n \"OAuthOperationError\",\n \"RunCredentialRenewalOperationError\",\n \"RunStateCompatibilityError\",\n \"SandboxChannelAOperationError\",\n \"SnapshotOperationError\",\n \"StartupDependencyError\",\n \"TelemetryExportError\",\n \"CodemodeOperationError\",\n \"CodemodeTokenRenewalOperationError\",\n \"WorkerLifecycleOperation\",\n \"WorkerLifecycleOperationError\",\n \"WorkerOperationError\",\n \"WorkflowWakeOperationError\",\n]);\n\nconst PUBLIC_TELEMETRY_ERROR_CODES = new Set([\n \"agent_command_wake_failed\",\n \"api_startup_failed\",\n \"api_uncaught_exception\",\n \"api_unhandled_rejection\",\n \"artifact_materializer_native_input_framing_failed\",\n \"artifact_materializer_native_snapshot_open_failed\",\n \"artifact_materializer_native_state_mismatch\",\n \"artifact_materializer_source_content_type_mismatch\",\n \"artifact_materializer_source_open_failed\",\n \"artifact_materializer_source_revalidation_failed\",\n \"artifact_materializer_source_stream_identity_mismatch\",\n \"cleared_goal_live_publish_failed\",\n \"codex_failover_checkpoint_failed\",\n \"codex_fleet_shadow_failed\",\n \"codex_lease_loss_checkpoint_failed\",\n \"codex_active_credential_read_failed\",\n \"command_yield_timeout\",\n \"conflict\",\n \"control_wake_dispatch_failed\",\n \"fenced_event_live_publish_failed\",\n \"forbidden\",\n \"host_export_batch_delivery_failed\",\n \"host_export_failure_settlement_stale\",\n \"host_export_pump_iteration_failed\",\n \"host_export_retention_prune_failed\",\n \"idempotency_conflict\",\n \"incompatible_exposed_ports\",\n \"internal_error\",\n \"limit_exceeded\",\n \"mcp_close_failed\",\n \"mcp_connect_failed\",\n \"mcp_tool_call_failed\",\n \"mcp_tools_list_failed\",\n \"mcp_transport_failed\",\n \"memory_edit_embedding_failed\",\n \"memory_hybrid_vector_failed\",\n \"memory_save_embedding_failed\",\n \"nats_auth_callout_start_failed\",\n \"nested_agent_depth_exceeded\",\n \"nested_agent_depth_override_forbidden\",\n \"not_found\",\n \"oauth_operation_failed\",\n \"otlp_export_failed\",\n \"payment_required\",\n \"provider_verification_failed\",\n \"sandbox_channel_a_cancelled\",\n \"sandbox_channel_a_lifecycle_conflict\",\n \"sandbox_channel_a_operation_failed\",\n \"sandbox_channel_a_provider_busy\",\n \"sandbox_channel_a_provider_unavailable\",\n \"screenshot_capture_failed\",\n \"session_event_live_publish_failed\",\n \"session_workflow_wake_failed\",\n \"snapshot_operation_failed\",\n \"startup_dependency_retry\",\n \"tool_list_too_large\",\n \"tool_result_too_large\",\n \"codemode_operation_failed\",\n \"unauthenticated\",\n \"upstream_unavailable\",\n \"validation_failed\",\n \"worker_draining\",\n \"worker_operation_failed\",\n \"worker_shutdown_request_failed\",\n \"workspace_control_live_publish_failed\",\n]);\n\nconst PUBLIC_TELEMETRY_ERROR_ORIGINS = new Set([\n \"api\",\n \"core\",\n \"db\",\n \"events\",\n \"host-export\",\n \"oauth\",\n \"observability\",\n \"runtime\",\n \"sandbox-computer\",\n \"sandbox-resume\",\n \"codemode\",\n \"worker\",\n \"worker-lifecycle\",\n]);\n\nexport type SandboxOperationMetricObservation = {\n backend: string;\n op: string;\n outcome: \"ok\" | \"not_found\" | \"failed\";\n durationMs: number;\n};\n\nexport function createObservability(\n settings: ObservabilitySettings,\n options: ObservabilityOptions,\n): Observability {\n return new Observability(settings, options);\n}\n\ntype MetricRegistration = {\n kind: \"counter\" | \"gauge\" | \"histogram\";\n labelNames: string[];\n};\n\nexport class Observability {\n private readonly registry = new Registry();\n private readonly counters = new Map<string, Counter<string>>();\n private readonly gauges = new Map<string, Gauge<string>>();\n private readonly histograms = new Map<string, Histogram<string>>();\n private readonly registrations = new Map<string, MetricRegistration>();\n private readonly pendingExports = new Set<Promise<void>>();\n private readonly now: () => number;\n private readonly exporter: (\n url: string,\n body: unknown,\n headers: Record<string, string>,\n ) => Promise<void>;\n private readonly resourceAttributes: Attributes;\n\n constructor(\n private readonly settings: ObservabilitySettings,\n private readonly options: ObservabilityOptions,\n ) {\n this.now = options.now ?? Date.now;\n this.exporter = options.exporter ?? defaultExporter;\n this.resourceAttributes = {\n \"service.name\": settings.serviceName,\n \"deployment.environment\": settings.environment,\n \"opengeni.component\": options.component,\n };\n this.registry.setDefaultLabels({\n service: settings.serviceName,\n environment: settings.environment,\n component: options.component,\n deployment_revision: settings.deploymentRevision ?? \"dev\",\n });\n if (settings.observabilityMetricsEnabled) {\n collectDefaultMetrics({ register: this.registry, prefix: \"opengeni_\" });\n this.setGauge({\n name: \"opengeni_build_info\",\n help: \"OpenGeni build information.\",\n labels: {\n version: buildVersion(),\n revision: settings.deploymentRevision ?? \"dev\",\n },\n value: 1,\n });\n this.registerSandboxRolloutConfig();\n this.registerTenancyCompatibilityLanes();\n }\n }\n\n /**\n * Publish every compatibility lane at zero on startup. Without this an\n * un-exercised lane has no series at all, and an operator cannot tell \"this\n * lane is dormant\" from \"this lane was never wired up\" - the two readings\n * that matter most to a cutover gate.\n */\n private registerTenancyCompatibilityLanes(): void {\n for (const lane of TENANCY_COMPATIBILITY_LANES) {\n this.incrementCounter({ ...TENANCY_COMPATIBILITY_LANE_METRIC, labels: { lane }, amount: 0 });\n }\n }\n\n private registerSandboxRolloutConfig(): void {\n const ownership = this.settings.sandboxOwnershipEnabled;\n const lazyConfigured = this.settings.sandboxLazyProvisionEnabled;\n const rigVerification = this.settings.rigVerificationLeaseOwnershipEnabled;\n if (\n typeof ownership !== \"boolean\" ||\n typeof lazyConfigured !== \"boolean\" ||\n typeof rigVerification !== \"boolean\"\n ) {\n return;\n }\n\n const values = [\n [\"ownership\", \"configured\", ownership],\n [\"ownership\", \"effective\", ownership],\n [\"lazy_provision\", \"configured\", lazyConfigured],\n [\"lazy_provision\", \"effective\", ownership && lazyConfigured],\n [\"rig_verification_lease_ownership\", \"configured\", rigVerification],\n [\"rig_verification_lease_ownership\", \"effective\", rigVerification],\n ] as const;\n for (const [feature, state, enabled] of values) {\n this.setGauge({\n name: \"opengeni_sandbox_rollout_config\",\n help: \"Configured and effective sandbox rollout state for this workload revision.\",\n labels: { feature, state },\n value: enabled ? 1 : 0,\n });\n }\n }\n\n debug(message: string, attributes: Attributes = {}): void {\n this.log(\"debug\", message, attributes);\n }\n\n info(message: string, attributes: Attributes = {}): void {\n this.log(\"info\", message, attributes);\n }\n\n warn(message: string, attributes: Attributes = {}): void {\n this.log(\"warn\", message, attributes);\n }\n\n error(message: string, attributes: Attributes = {}): void {\n this.log(\"error\", message, attributes);\n }\n\n log(\n level: \"debug\" | \"info\" | \"warn\" | \"error\",\n message: string,\n attributes: Attributes = {},\n ): void {\n const publicAttributes = projectPublicTelemetryAttributes(attributes);\n if (!this.settings.observabilityStructuredLogs) {\n if (level === \"warn\") {\n console.warn(message);\n } else if (level === \"error\") {\n console.error(message);\n } else {\n console.log(message);\n }\n return;\n }\n const record = {\n timestamp: new Date(this.now()).toISOString(),\n level,\n message,\n service: this.settings.serviceName,\n environment: this.settings.environment,\n component: this.options.component,\n ...cleanAttributes(publicAttributes),\n };\n const serialized = JSON.stringify(record);\n if (level === \"warn\") {\n console.warn(serialized);\n } else if (level === \"error\") {\n console.error(serialized);\n } else {\n console.log(serialized);\n }\n }\n\n startSpan(name: string, attributes: Attributes = {}): Span {\n const traceId = randomHex(16);\n const spanId = randomHex(8);\n const startMs = this.now();\n let ended = false;\n return {\n traceId,\n spanId,\n end: (input = {}) => {\n if (ended) {\n return;\n }\n ended = true;\n const telemetryError =\n input.error !== undefined && input.error !== null\n ? projectSpanErrorForTelemetry(input.error)\n : undefined;\n const errorAttributes = telemetryError ? errorToAttributes(telemetryError) : {};\n this.exportSpan({\n traceId,\n spanId,\n name,\n startMs,\n endMs: this.now(),\n attributes: {\n ...projectPublicTelemetryAttributes({\n ...attributes,\n ...input.attributes,\n ...errorAttributes,\n }),\n },\n ...(telemetryError ? { error: telemetryError } : {}),\n });\n },\n };\n }\n\n recordHttpRequest(input: {\n method: string;\n route: string;\n status: number;\n durationSeconds: number;\n }): void {\n this.incrementCounter({\n name: \"opengeni_http_requests_total\",\n help: \"Total HTTP requests handled by OpenGeni.\",\n labels: {\n method: input.method,\n route: input.route,\n status: String(input.status),\n component: this.options.component,\n },\n });\n this.observeHistogram({\n name: \"opengeni_http_request_duration_seconds\",\n help: \"HTTP request duration in seconds.\",\n buckets: httpHistogramBuckets,\n value: input.durationSeconds,\n labels: {\n method: input.method,\n route: input.route,\n component: this.options.component,\n },\n });\n }\n\n recordWorkerActivity(input: { activity: string; status: string; durationSeconds: number }): void {\n this.incrementCounter({\n name: \"opengeni_worker_activity_runs_total\",\n help: \"Total worker activity executions.\",\n labels: {\n activity: input.activity,\n status: input.status,\n component: this.options.component,\n },\n });\n this.observeHistogram({\n name: \"opengeni_worker_activity_duration_seconds\",\n help: \"Worker activity duration in seconds.\",\n buckets: durationHistogramBuckets,\n value: input.durationSeconds,\n labels: {\n activity: input.activity,\n component: this.options.component,\n },\n });\n }\n\n incrementCounter(input: {\n name: string;\n help?: string;\n labels?: MetricLabels;\n amount?: number;\n }): void {\n if (!this.settings.observabilityMetricsEnabled) {\n return;\n }\n const labels = normalizeLabels(input.labels);\n const counter = this.counter(\n input.name,\n input.help ?? `${input.name} counter.`,\n Object.keys(labels),\n );\n counter.inc(labels as never, input.amount ?? 1);\n }\n\n setGauge(input: { name: string; help?: string; labels?: MetricLabels; value: number }): void {\n if (!this.settings.observabilityMetricsEnabled) {\n return;\n }\n const labels = normalizeLabels(input.labels);\n const gauge = this.gauge(input.name, input.help ?? `${input.name} gauge.`, Object.keys(labels));\n gauge.set(labels as never, input.value);\n }\n\n incrementGauge(input: {\n name: string;\n help?: string;\n labels?: MetricLabels;\n amount?: number;\n }): void {\n if (!this.settings.observabilityMetricsEnabled) {\n return;\n }\n const labels = normalizeLabels(input.labels);\n const gauge = this.gauge(input.name, input.help ?? `${input.name} gauge.`, Object.keys(labels));\n gauge.inc(labels as never, input.amount ?? 1);\n }\n\n observeHistogram(input: {\n name: string;\n help?: string;\n labels?: MetricLabels;\n value: number;\n buckets?: number[];\n }): void {\n if (!this.settings.observabilityMetricsEnabled) {\n return;\n }\n const labels = normalizeLabels(input.labels);\n const histogram = this.histogram(\n input.name,\n input.help ?? `${input.name} histogram.`,\n Object.keys(labels),\n input.buckets ?? durationHistogramBuckets,\n );\n histogram.observe(labels as never, input.value);\n }\n\n async prometheusMetrics(): Promise<string> {\n if (!this.settings.observabilityMetricsEnabled) {\n return \"\";\n }\n return await this.registry.metrics();\n }\n\n /** Wait for every OTLP export accepted before or during this drain. */\n async flush(): Promise<void> {\n while (this.pendingExports.size > 0) {\n await Promise.allSettled([...this.pendingExports]);\n }\n }\n\n private counter(name: string, help: string, labelNames: string[]): Counter<string> {\n const existing = this.counters.get(name);\n if (existing) {\n this.assertRegistration(name, \"counter\", labelNames);\n return existing;\n }\n this.register(name, \"counter\", labelNames);\n const metric = new Counter({ name, help, labelNames, registers: [this.registry] });\n this.counters.set(name, metric);\n return metric;\n }\n\n private gauge(name: string, help: string, labelNames: string[]): Gauge<string> {\n const existing = this.gauges.get(name);\n if (existing) {\n this.assertRegistration(name, \"gauge\", labelNames);\n return existing;\n }\n this.register(name, \"gauge\", labelNames);\n const metric = new Gauge({ name, help, labelNames, registers: [this.registry] });\n this.gauges.set(name, metric);\n return metric;\n }\n\n private histogram(\n name: string,\n help: string,\n labelNames: string[],\n buckets: number[],\n ): Histogram<string> {\n const existing = this.histograms.get(name);\n if (existing) {\n this.assertRegistration(name, \"histogram\", labelNames);\n return existing;\n }\n this.register(name, \"histogram\", labelNames);\n const metric = new Histogram({ name, help, labelNames, buckets, registers: [this.registry] });\n this.histograms.set(name, metric);\n return metric;\n }\n\n private register(name: string, kind: MetricRegistration[\"kind\"], labelNames: string[]): void {\n const sorted = [...labelNames].sort();\n this.registrations.set(name, { kind, labelNames: sorted });\n }\n\n private assertRegistration(\n name: string,\n kind: MetricRegistration[\"kind\"],\n labelNames: string[],\n ): void {\n const registration = this.registrations.get(name);\n const sorted = [...labelNames].sort();\n if (\n !registration ||\n registration.kind !== kind ||\n registration.labelNames.length !== sorted.length ||\n registration.labelNames.some((label, index) => label !== sorted[index])\n ) {\n throw new Error(\n `Metric ${name} was already registered as ${registration?.kind ?? \"unknown\"} ` +\n `with labels [${registration?.labelNames.join(\",\") ?? \"\"}], not ${kind} [${sorted.join(\",\")}]`,\n );\n }\n }\n\n private exportSpan(span: {\n traceId: string;\n spanId: string;\n name: string;\n startMs: number;\n endMs: number;\n attributes: Attributes;\n error?: TelemetrySpanError;\n }): void {\n if (!this.settings.observabilityOtlpEndpoint) {\n return;\n }\n const endpoint = `${this.settings.observabilityOtlpEndpoint.replace(/\\/$/, \"\")}/v1/traces`;\n const body = {\n resourceSpans: [\n {\n resource: {\n attributes: otlpAttributes(this.resourceAttributes),\n },\n scopeSpans: [\n {\n scope: {\n name: \"@opengeni/observability\",\n version: \"0.1.0\",\n },\n spans: [\n {\n traceId: span.traceId,\n spanId: span.spanId,\n name: span.name,\n kind: 1,\n startTimeUnixNano: millisToNanos(span.startMs),\n endTimeUnixNano: millisToNanos(span.endMs),\n attributes: otlpAttributes(span.attributes),\n status: span.error ? { code: 2, message: span.error.statusMessage } : { code: 1 },\n },\n ],\n },\n ],\n },\n ],\n };\n let pendingExport: Promise<void>;\n pendingExport = Promise.resolve()\n .then(() =>\n this.exporter(endpoint, body, parseHeaders(this.settings.observabilityOtlpHeaders)),\n )\n .catch(() => {\n this.warn(\"OTLP span export failed\", {\n errorClass: \"TelemetryExportError\",\n errorCode: \"otlp_export_failed\",\n origin: \"observability\",\n });\n })\n .finally(() => {\n this.pendingExports.delete(pendingExport);\n });\n this.pendingExports.add(pendingExport);\n }\n}\n\n/**\n * Convert routed sandbox-provider observations into one bounded Prometheus\n * contract shared by API-direct and worker-turn execution. Provider/session\n * identifiers, commands, paths, and other request data can never become labels:\n * a future backend or operation is deliberately collapsed to `unknown` until\n * this allowlist is reviewed.\n *\n * The returned callback is fail-safe. Metrics must never change the provider\n * operation's result; a registration/exporter error is counted best-effort and\n * then swallowed at this telemetry boundary.\n */\nexport function sandboxOperationMetricObserver(\n observability: Observability,\n): (observation: SandboxOperationMetricObservation) => void {\n return (observation) => {\n const backend = SANDBOX_OPERATION_BACKENDS.has(observation.backend)\n ? observation.backend\n : \"unknown\";\n const op = SANDBOX_OPERATION_NAMES.has(observation.op) ? observation.op : \"unknown\";\n try {\n observability.incrementCounter({\n name: \"opengeni_sandbox_operations_total\",\n help: \"Physical routed sandbox provider operations by backend, operation, and outcome.\",\n labels: { backend, op, outcome: observation.outcome },\n });\n observability.observeHistogram({\n name: \"opengeni_sandbox_operation_duration_seconds\",\n help: \"Physical routed sandbox provider-operation duration in seconds.\",\n labels: { backend, op },\n value: Math.max(0, observation.durationMs) / 1_000,\n });\n } catch {\n try {\n observability.incrementCounter({\n name: \"opengeni_observability_observer_errors_total\",\n help: \"Observability observer failures isolated from product execution.\",\n labels: { observer: \"sandbox_operation\" },\n });\n } catch {\n // The metrics registry itself is unhealthy. Product execution remains\n // authoritative and must not inherit an observability failure.\n }\n }\n };\n}\n\nexport type InteractionOperationMetricObservation = {\n resource: string;\n operation: string;\n outcome: string;\n mode: string;\n durationMs: number;\n replayed?: boolean | undefined;\n};\n\n/** Safe low-cardinality telemetry for Browser/Computer control operations.\n * Resource ids, URLs, locators, page/app text, and input values are excluded by\n * construction. Unknown future enum values collapse until explicitly reviewed. */\nexport function interactionOperationMetricObserver(\n observability: Observability | null | undefined,\n): (observation: InteractionOperationMetricObservation) => void {\n if (!observability) return () => undefined;\n return (observation) => {\n if (observation.replayed) return;\n const resource = boundedMetricEnum(INTERACTION_RESOURCES, observation.resource);\n const operation = boundedMetricEnum(INTERACTION_OPERATIONS, observation.operation);\n const outcome = boundedMetricEnum(INTERACTION_OUTCOMES, observation.outcome);\n const mode = boundedMetricEnum(INTERACTION_MODES, observation.mode);\n try {\n observability.incrementCounter({\n name: \"opengeni_interaction_operations_total\",\n help: \"Browser and Computer operations by bounded resource, operation, mode, and outcome.\",\n labels: { resource, operation, mode, outcome },\n });\n observability.observeHistogram({\n name: \"opengeni_interaction_operation_duration_seconds\",\n help: \"Browser and Computer operation duration in seconds.\",\n labels: { resource, operation, mode },\n value: boundedMetricDuration(observation.durationMs),\n });\n } catch {\n recordObserverFailure(observability, \"interaction_operation\");\n }\n };\n}\n\nexport type InteractionAuthMetricObservation = {\n state: string;\n durationMs: number;\n replayed?: boolean | undefined;\n};\n\nexport function interactionAuthMetricObserver(\n observability: Observability | null | undefined,\n): (observation: InteractionAuthMetricObservation) => void {\n if (!observability) return () => undefined;\n return (observation) => {\n if (observation.replayed) return;\n const state = boundedMetricEnum(INTERACTION_AUTH_STATES, observation.state);\n try {\n observability.incrementCounter({\n name: \"opengeni_interaction_auth_transitions_total\",\n help: \"Browser authentication transitions by bounded resulting state.\",\n labels: { state },\n });\n observability.observeHistogram({\n name: \"opengeni_interaction_auth_transition_duration_seconds\",\n help: \"Browser authentication transition request duration in seconds.\",\n labels: { state },\n value: boundedMetricDuration(observation.durationMs),\n });\n } catch {\n recordObserverFailure(observability, \"interaction_auth\");\n }\n };\n}\n\nexport type InteractionInterventionMetricObservation = {\n kind: string;\n outcome: string;\n waitMs?: number | undefined;\n replayed?: boolean | undefined;\n};\n\nexport function interactionInterventionMetricObserver(\n observability: Observability | null | undefined,\n): (observation: InteractionInterventionMetricObservation) => void {\n if (!observability) return () => undefined;\n return (observation) => {\n if (observation.replayed) return;\n const kind = boundedMetricEnum(INTERACTION_INTERVENTION_KINDS, observation.kind);\n const outcome = boundedMetricEnum(INTERACTION_INTERVENTION_OUTCOMES, observation.outcome);\n try {\n observability.incrementCounter({\n name: \"opengeni_interaction_interventions_total\",\n help: \"Human browser/computer interventions by bounded kind and outcome.\",\n labels: { kind, outcome },\n });\n if (observation.waitMs !== undefined) {\n observability.observeHistogram({\n name: \"opengeni_interaction_intervention_wait_seconds\",\n help: \"Time an interaction intervention remained open before settlement.\",\n labels: { kind, outcome },\n value: boundedMetricDuration(observation.waitMs),\n });\n }\n } catch {\n recordObserverFailure(observability, \"interaction_intervention\");\n }\n };\n}\n\nexport type WorkspaceInsightsMetricObservation = {\n range: string;\n providerFiltered: boolean;\n modelFiltered: boolean;\n outcome: string;\n durationMs: number;\n};\n\n/**\n * Identity-free route timing for Workspace Insights. The dedicated two-second\n * bucket is the service target; fixed enums and filter-presence flags keep\n * tenant ids and caller-supplied provider/model values out of telemetry.\n */\nexport function workspaceInsightsMetricObserver(\n observability: Observability | null | undefined,\n): (observation: WorkspaceInsightsMetricObservation) => void {\n if (!observability) return () => undefined;\n return (observation) => {\n const range = boundedMetricEnum(WORKSPACE_INSIGHTS_RANGES, observation.range);\n const outcome = boundedMetricEnum(WORKSPACE_INSIGHTS_OUTCOMES, observation.outcome);\n const providerFilter = observation.providerFiltered ? \"filtered\" : \"all\";\n const modelFilter = observation.modelFiltered ? \"filtered\" : \"all\";\n const durationSeconds = boundedMetricDuration(observation.durationMs);\n try {\n observability.observeHistogram({\n name: \"opengeni_workspace_insights_request_duration_seconds\",\n help: \"Workspace Insights route service duration by bounded range, filter presence, and outcome.\",\n buckets: workspaceInsightsDurationHistogramBuckets,\n labels: {\n range,\n provider_filter: providerFilter,\n model_filter: modelFilter,\n outcome,\n },\n value: durationSeconds,\n });\n observability.info(\"Workspace Insights request measured\", {\n surface: \"workspace_insights\",\n eventType: \"request_latency\",\n route: \"/v1/workspaces/:workspaceId/insights\",\n outcome,\n durationMs: Math.round(durationSeconds * 1_000),\n });\n } catch {\n recordObserverFailure(observability, \"workspace_insights\");\n }\n };\n}\n\nfunction boundedMetricEnum(allowed: ReadonlySet<string>, value: string): string {\n return allowed.has(value) ? value : \"unknown\";\n}\n\nfunction boundedMetricDuration(durationMs: number): number {\n return Number.isFinite(durationMs) ? Math.max(0, durationMs) / 1_000 : 0;\n}\n\nfunction recordObserverFailure(observability: Observability, observer: string): void {\n try {\n observability.incrementCounter({\n name: \"opengeni_observability_observer_errors_total\",\n help: \"Observability observer failures isolated from product execution.\",\n labels: { observer },\n });\n } catch {\n // The metrics registry itself is unhealthy. Product execution remains\n // authoritative and must not inherit an observability failure.\n }\n}\n\nexport type StartupDependencyRetryEvent = {\n label: string;\n attempt: number;\n attempts: number;\n delayMs: number;\n error: unknown;\n};\n\nexport function logStartupDependencyRetry(\n observability: Observability,\n event: StartupDependencyRetryEvent,\n): void {\n const dependency = PUBLIC_STARTUP_DEPENDENCIES.has(event.label) ? event.label : \"Dependency\";\n observability.warn(\n `Startup dependency ${dependency} connection failed; retrying (${event.attempt}/${event.attempts} in ${event.delayMs}ms)`,\n {\n dependency,\n attempt: event.attempt,\n attempts: event.attempts,\n delayMs: event.delayMs,\n errorClass: \"StartupDependencyError\",\n errorCode: \"startup_dependency_retry\",\n origin: \"observability\",\n },\n );\n}\n\nfunction normalizeLabels(labels: MetricLabels = {}): Record<string, string> {\n return Object.fromEntries(\n Object.entries(labels)\n .filter(([, value]) => value !== undefined && value !== null)\n .map(([key, value]): [string, string] => [key, String(value)])\n .sort((left, right) => left[0].localeCompare(right[0])),\n );\n}\n\nfunction buildVersion(): string {\n return process.env.OPENGENI_VERSION ?? process.env.npm_package_version ?? \"dev\";\n}\n\nfunction cleanAttributes(attributes: Attributes): Record<string, string | number | boolean | null> {\n return Object.fromEntries(\n Object.entries(attributes).filter(([, value]) => value !== undefined),\n ) as Record<string, string | number | boolean | null>;\n}\n\nfunction projectPublicTelemetryAttributes(attributes: Attributes): Attributes {\n if (\"errorClass\" in attributes || \"errorCode\" in attributes) {\n return {\n ...projectStartupDependencyAttributes(attributes),\n ...projectPublicChannelADiagnosticAttributes(attributes),\n ...projectApiFatalDiagnosticAttributes(attributes),\n ...projectPublicDiagnosticAttributes(attributes),\n };\n }\n return Object.fromEntries(\n Object.entries(attributes).filter(([key, value]) => {\n if (value === undefined) return false;\n if (PUBLIC_TELEMETRY_ATTRIBUTE_KEYS.has(key)) return true;\n const pattern = PUBLIC_TELEMETRY_OPAQUE_ATTRIBUTE_PATTERNS.get(key);\n return typeof value === \"string\" && pattern?.test(value) === true;\n }),\n );\n}\n\nfunction projectApiFatalDiagnosticAttributes(attributes: Attributes): Attributes {\n if (attributes.errorClass !== \"ApiFatalOperationError\") return {};\n const phase = attributes.phase;\n const reasonKind = attributes.reasonKind;\n return {\n ...(typeof phase === \"string\" && PUBLIC_API_FATAL_PHASES.has(phase) ? { phase } : {}),\n ...(typeof reasonKind === \"string\" && PUBLIC_API_FATAL_REASON_KINDS.has(reasonKind)\n ? { reasonKind }\n : {}),\n };\n}\n\nfunction projectStartupDependencyAttributes(attributes: Attributes): Attributes {\n if (\n attributes.errorClass !== \"StartupDependencyError\" ||\n attributes.errorCode !== \"startup_dependency_retry\"\n ) {\n return {};\n }\n const dependency = attributes.dependency;\n const attempt = attributes.attempt;\n const attempts = attributes.attempts;\n const delayMs = attributes.delayMs;\n return {\n ...(typeof dependency === \"string\" && PUBLIC_STARTUP_DEPENDENCIES.has(dependency)\n ? { dependency }\n : {}),\n ...(typeof attempt === \"number\" && Number.isInteger(attempt) && attempt > 0 ? { attempt } : {}),\n ...(typeof attempts === \"number\" && Number.isInteger(attempts) && attempts > 0\n ? { attempts }\n : {}),\n ...(typeof delayMs === \"number\" && Number.isFinite(delayMs) && delayMs >= 0 ? { delayMs } : {}),\n };\n}\n\nfunction projectPublicChannelADiagnosticAttributes(attributes: Attributes): Attributes {\n if (attributes.errorClass !== \"SandboxChannelAOperationError\") return {};\n const backend = attributes.backend;\n const op = attributes.op;\n const outcome = attributes.outcome;\n const reason = attributes.reason;\n const durationMs = attributes.durationMs;\n const sandboxLeaseKey = attributes.sandboxLeaseKey;\n return {\n ...(typeof backend === \"string\" && SANDBOX_OPERATION_BACKENDS.has(backend) ? { backend } : {}),\n ...(typeof op === \"string\" && PUBLIC_CHANNEL_A_OPERATIONS.has(op) ? { op } : {}),\n ...(outcome === \"failed\" ? { outcome } : {}),\n ...(typeof reason === \"string\" && PUBLIC_CHANNEL_A_FAILURE_REASONS.has(reason)\n ? { reason }\n : {}),\n ...(typeof durationMs === \"number\" && Number.isFinite(durationMs) && durationMs >= 0\n ? { durationMs }\n : {}),\n ...(typeof sandboxLeaseKey === \"string\" &&\n PUBLIC_TELEMETRY_OPAQUE_ATTRIBUTE_PATTERNS.get(\"sandboxLeaseKey\")?.test(sandboxLeaseKey)\n ? { sandboxLeaseKey }\n : {}),\n };\n}\n\nfunction projectPublicDiagnosticAttributes(attributes: Attributes): Attributes {\n const errorClass = attributes.errorClass;\n const errorCode = attributes.errorCode;\n const status = attributes.status;\n const origin = attributes.origin;\n const correlationId = attributes.correlationId;\n return {\n errorClass:\n typeof errorClass === \"string\" && PUBLIC_TELEMETRY_ERROR_CLASSES.has(errorClass)\n ? errorClass\n : \"OperationError\",\n ...(typeof errorCode === \"string\" && PUBLIC_TELEMETRY_ERROR_CODES.has(errorCode)\n ? { errorCode }\n : {}),\n ...(typeof status === \"number\" && Number.isInteger(status) && status >= 100 && status <= 599\n ? { status }\n : {}),\n ...(typeof origin === \"string\" && PUBLIC_TELEMETRY_ERROR_ORIGINS.has(origin) ? { origin } : {}),\n ...(typeof correlationId === \"string\" &&\n PUBLIC_TELEMETRY_OPAQUE_ATTRIBUTE_PATTERNS.get(\"correlationId\")?.test(correlationId)\n ? { correlationId }\n : {}),\n };\n}\n\ntype TelemetrySpanError = {\n type: string;\n statusCode?: number;\n statusMessage: string;\n};\n\n/**\n * External OTLP projection. It intentionally exports only error class/status\n * metadata and never mutates canonical OpenGeni errors, events, or history.\n */\nfunction projectSpanErrorForTelemetry(error: unknown): TelemetrySpanError {\n const statusCode = errorStatusCode(error);\n return {\n type: \"OperationError\",\n ...(statusCode === undefined ? {} : { statusCode }),\n statusMessage: statusCode === undefined ? \"operation failed\" : `HTTP ${statusCode}`,\n };\n}\n\nfunction errorStatusCode(error: unknown): number | undefined {\n if (typeof error !== \"object\" || error === null) return undefined;\n try {\n const value = (error as { status?: unknown; statusCode?: unknown }).status;\n const statusCode =\n Number.isInteger(value) && typeof value === \"number\"\n ? value\n : (error as { statusCode?: unknown }).statusCode;\n return Number.isInteger(statusCode) &&\n typeof statusCode === \"number\" &&\n statusCode >= 100 &&\n statusCode <= 599\n ? statusCode\n : undefined;\n } catch {\n // OTLP projection must never mask the exact internal failure.\n return undefined;\n }\n}\n\nfunction errorToAttributes(error: TelemetrySpanError): Attributes {\n return {\n \"error.type\": error.type,\n ...(error.statusCode === undefined ? {} : { \"error.status_code\": error.statusCode }),\n };\n}\n\nfunction otlpAttributes(\n attributes: Attributes,\n): Array<{ key: string; value: Record<string, string | number | boolean> }> {\n return Object.entries(cleanAttributes(attributes)).map(([key, value]) => ({\n key,\n value: otlpValue(value),\n }));\n}\n\nfunction otlpValue(\n value: string | number | boolean | null,\n): Record<string, string | number | boolean> {\n if (typeof value === \"number\") {\n return Number.isInteger(value) ? { intValue: value } : { doubleValue: value };\n }\n if (typeof value === \"boolean\") {\n return { boolValue: value };\n }\n return { stringValue: value === null ? \"\" : boundedOtlpString(value) };\n}\n\nfunction boundedOtlpString(value: string): string {\n const bytes = new TextEncoder().encode(value);\n if (bytes.byteLength <= 512) return value;\n return `${new TextDecoder().decode(bytes.slice(0, 509))}…`;\n}\n\nfunction millisToNanos(ms: number): string {\n return String(BigInt(Math.round(ms)) * 1_000_000n);\n}\n\nfunction randomHex(bytes: number): string {\n const values = crypto.getRandomValues(new Uint8Array(bytes));\n return Array.from(values, (value) => value.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\nexport function parseHeaders(value: string): Record<string, string> {\n if (!value.trim()) {\n return {};\n }\n const entries: Array<[string, string]> = value\n .split(\",\")\n .map((pair): [string, string] => {\n const separator = pair.indexOf(\"=\");\n if (separator === -1) {\n return [pair.trim(), \"\"];\n }\n return [pair.slice(0, separator).trim(), pair.slice(separator + 1).trim()];\n })\n .filter(([key]) => key.length > 0);\n return Object.fromEntries(entries);\n}\n\nasync function defaultExporter(\n url: string,\n body: unknown,\n headers: Record<string, string>,\n): Promise<void> {\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n ...headers,\n },\n body: JSON.stringify(body),\n });\n if (!response.ok) {\n throw new Error(`OTLP endpoint returned HTTP ${response.status}`);\n }\n}\n"],"mappings":"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,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,IAAM,+BAA+B,oBAAI,IAAI;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,IAAM,iCAAiC,oBAAI,IAAI;AAAA,EAC7C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AASM,SAAS,oBACd,UACA,SACe;AACf,SAAO,IAAI,cAAc,UAAU,OAAO;AAC5C;AAOO,IAAM,gBAA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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengeni/observability",
3
- "version": "0.8.6-canary.2",
3
+ "version": "0.8.8-canary.0",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",
@@ -31,7 +31,7 @@
31
31
  "prepublishOnly": "bash ../../scripts/prepublish-guard"
32
32
  },
33
33
  "dependencies": {
34
- "@opengeni/contracts": "^2.5.0-canary.2",
34
+ "@opengeni/contracts": "^2.6.0-canary.0",
35
35
  "prom-client": "^15.1.3"
36
36
  }
37
37
  }
package/src/index.ts CHANGED
@@ -340,6 +340,20 @@ const PUBLIC_CHANNEL_A_FAILURE_REASONS = new Set([
340
340
  "unexpected",
341
341
  ]);
342
342
 
343
+ const PUBLIC_API_FATAL_PHASES = new Set(["startup", "running"]);
344
+ const PUBLIC_API_FATAL_REASON_KINDS = new Set([
345
+ "bigint",
346
+ "boolean",
347
+ "error",
348
+ "function",
349
+ "null",
350
+ "number",
351
+ "object",
352
+ "string",
353
+ "symbol",
354
+ "undefined",
355
+ ]);
356
+
343
357
  /**
344
358
  * Public diagnostic values are protocol constants, never values inferred from
345
359
  * an exception's name, constructor, code, message, or enumerable properties.
@@ -347,6 +361,7 @@ const PUBLIC_CHANNEL_A_FAILURE_REASONS = new Set([
347
361
  * are omitted rather than copied through based on syntax.
348
362
  */
349
363
  const PUBLIC_TELEMETRY_ERROR_CLASSES = new Set([
364
+ "ApiFatalOperationError",
350
365
  "OperationError",
351
366
  "CodexCheckpointOperationError",
352
367
  "CodexFleetShadowOperationError",
@@ -380,6 +395,9 @@ const PUBLIC_TELEMETRY_ERROR_CLASSES = new Set([
380
395
 
381
396
  const PUBLIC_TELEMETRY_ERROR_CODES = new Set([
382
397
  "agent_command_wake_failed",
398
+ "api_startup_failed",
399
+ "api_uncaught_exception",
400
+ "api_unhandled_rejection",
383
401
  "artifact_materializer_native_input_framing_failed",
384
402
  "artifact_materializer_native_snapshot_open_failed",
385
403
  "artifact_materializer_native_state_mismatch",
@@ -484,6 +502,7 @@ export class Observability {
484
502
  private readonly gauges = new Map<string, Gauge<string>>();
485
503
  private readonly histograms = new Map<string, Histogram<string>>();
486
504
  private readonly registrations = new Map<string, MetricRegistration>();
505
+ private readonly pendingExports = new Set<Promise<void>>();
487
506
  private readonly now: () => number;
488
507
  private readonly exporter: (
489
508
  url: string,
@@ -774,6 +793,13 @@ export class Observability {
774
793
  return await this.registry.metrics();
775
794
  }
776
795
 
796
+ /** Wait for every OTLP export accepted before or during this drain. */
797
+ async flush(): Promise<void> {
798
+ while (this.pendingExports.size > 0) {
799
+ await Promise.allSettled([...this.pendingExports]);
800
+ }
801
+ }
802
+
777
803
  private counter(name: string, help: string, labelNames: string[]): Counter<string> {
778
804
  const existing = this.counters.get(name);
779
805
  if (existing) {
@@ -882,15 +908,22 @@ export class Observability {
882
908
  },
883
909
  ],
884
910
  };
885
- void this.exporter(endpoint, body, parseHeaders(this.settings.observabilityOtlpHeaders)).catch(
886
- () => {
911
+ let pendingExport: Promise<void>;
912
+ pendingExport = Promise.resolve()
913
+ .then(() =>
914
+ this.exporter(endpoint, body, parseHeaders(this.settings.observabilityOtlpHeaders)),
915
+ )
916
+ .catch(() => {
887
917
  this.warn("OTLP span export failed", {
888
918
  errorClass: "TelemetryExportError",
889
919
  errorCode: "otlp_export_failed",
890
920
  origin: "observability",
891
921
  });
892
- },
893
- );
922
+ })
923
+ .finally(() => {
924
+ this.pendingExports.delete(pendingExport);
925
+ });
926
+ this.pendingExports.add(pendingExport);
894
927
  }
895
928
  }
896
929
 
@@ -1167,6 +1200,7 @@ function projectPublicTelemetryAttributes(attributes: Attributes): Attributes {
1167
1200
  return {
1168
1201
  ...projectStartupDependencyAttributes(attributes),
1169
1202
  ...projectPublicChannelADiagnosticAttributes(attributes),
1203
+ ...projectApiFatalDiagnosticAttributes(attributes),
1170
1204
  ...projectPublicDiagnosticAttributes(attributes),
1171
1205
  };
1172
1206
  }
@@ -1180,6 +1214,18 @@ function projectPublicTelemetryAttributes(attributes: Attributes): Attributes {
1180
1214
  );
1181
1215
  }
1182
1216
 
1217
+ function projectApiFatalDiagnosticAttributes(attributes: Attributes): Attributes {
1218
+ if (attributes.errorClass !== "ApiFatalOperationError") return {};
1219
+ const phase = attributes.phase;
1220
+ const reasonKind = attributes.reasonKind;
1221
+ return {
1222
+ ...(typeof phase === "string" && PUBLIC_API_FATAL_PHASES.has(phase) ? { phase } : {}),
1223
+ ...(typeof reasonKind === "string" && PUBLIC_API_FATAL_REASON_KINDS.has(reasonKind)
1224
+ ? { reasonKind }
1225
+ : {}),
1226
+ };
1227
+ }
1228
+
1183
1229
  function projectStartupDependencyAttributes(attributes: Attributes): Attributes {
1184
1230
  if (
1185
1231
  attributes.errorClass !== "StartupDependencyError" ||