@opengeni/observability 0.8.32 → 0.8.33-canary.36239117573001
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 +1 -0
- package/dist/index.js +51 -2
- package/dist/index.js.map +1 -1
- package/dist/log-throttle.d.ts +23 -0
- package/package.json +2 -2
- package/src/index.ts +25 -0
- package/src/log-throttle.ts +46 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type TraceContext } from "./trace-context.js";
|
|
2
2
|
import { type FailureDiagnosticInput } from "./failure-diagnostic.js";
|
|
3
3
|
export type { FailureDiagnosticInput } from "./failure-diagnostic.js";
|
|
4
|
+
export { createLogThrottle, type LogThrottle } from "./log-throttle.js";
|
|
4
5
|
export { currentTraceContext, withTraceContext, parseTraceparent, traceparent, admissionTraceContext, linkCurrentSpanToAdmission, type TraceContext, } from "./trace-context.js";
|
|
5
6
|
export type AttributeValue = string | number | boolean | null | undefined;
|
|
6
7
|
export type Attributes = Record<string, AttributeValue>;
|
package/dist/index.js
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
import { createHash as createHash3 } from "crypto";
|
|
3
3
|
import { collectDefaultMetrics, Counter, Gauge, Histogram, Registry } from "prom-client";
|
|
4
4
|
import { SandboxBackend } from "@opengeni/contracts";
|
|
5
|
+
import {
|
|
6
|
+
CLIENT_ERROR_REVISION_PATTERN,
|
|
7
|
+
CLIENT_ERROR_ROUTE_PATTERN
|
|
8
|
+
} from "@opengeni/contracts/client-error-report";
|
|
5
9
|
|
|
6
10
|
// src/trace-context.ts
|
|
7
11
|
import { AsyncLocalStorage } from "async_hooks";
|
|
@@ -269,6 +273,32 @@ function failureDiagnostic(input, revision) {
|
|
|
269
273
|
};
|
|
270
274
|
}
|
|
271
275
|
|
|
276
|
+
// src/log-throttle.ts
|
|
277
|
+
function createLogThrottle(options) {
|
|
278
|
+
const intervalMs = Math.max(0, options.intervalMs);
|
|
279
|
+
const maxKeys = Math.max(1, Math.floor(options.maxKeys ?? 1024));
|
|
280
|
+
const now = options.now ?? Date.now;
|
|
281
|
+
const entries = /* @__PURE__ */ new Map();
|
|
282
|
+
return {
|
|
283
|
+
admit(key) {
|
|
284
|
+
const at = now();
|
|
285
|
+
const entry = entries.get(key);
|
|
286
|
+
if (entry && at >= entry.admittedAt && at - entry.admittedAt < intervalMs) {
|
|
287
|
+
entry.suppressed += 1;
|
|
288
|
+
return null;
|
|
289
|
+
}
|
|
290
|
+
const suppressedCount = entry?.suppressed ?? 0;
|
|
291
|
+
entries.delete(key);
|
|
292
|
+
if (entries.size >= maxKeys) {
|
|
293
|
+
const oldest = entries.keys().next();
|
|
294
|
+
if (!oldest.done) entries.delete(oldest.value);
|
|
295
|
+
}
|
|
296
|
+
entries.set(key, { admittedAt: at, suppressed: 0 });
|
|
297
|
+
return { suppressedCount };
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
|
|
272
302
|
// src/index.ts
|
|
273
303
|
function sandboxLeaseTelemetryKey(workspaceId, sandboxGroupId) {
|
|
274
304
|
return `slk_${createHash3("sha256").update("opengeni:sandbox-lease-telemetry:v1\0").update(workspaceId).update("\0").update(sandboxGroupId).digest("hex").slice(0, 32)}`;
|
|
@@ -466,11 +496,17 @@ var PUBLIC_TELEMETRY_ATTRIBUTE_KEYS = /* @__PURE__ */ new Set([
|
|
|
466
496
|
"estimatedOriginalTokens",
|
|
467
497
|
"estimatedDeliveredTokens",
|
|
468
498
|
"fullEvidenceAvailable",
|
|
469
|
-
"retainedOutputKind"
|
|
499
|
+
"retainedOutputKind",
|
|
500
|
+
"suppressedCount"
|
|
470
501
|
]);
|
|
471
502
|
var PUBLIC_TELEMETRY_OPAQUE_ATTRIBUTE_PATTERNS = /* @__PURE__ */ new Map([
|
|
472
503
|
["sandboxLeaseKey", /^slk_[0-9a-f]{32}$/],
|
|
473
|
-
["correlationId", /^[A-Za-z0-9._:-]{1,128}$/]
|
|
504
|
+
["correlationId", /^[A-Za-z0-9._:-]{1,128}$/],
|
|
505
|
+
// Web error beacon: a route PATTERN of lowercase literal and `$param`
|
|
506
|
+
// segments (never a concrete path or id) and the bundle revision token, in
|
|
507
|
+
// the exact wire grammar the API route admits.
|
|
508
|
+
["clientRoute", CLIENT_ERROR_ROUTE_PATTERN],
|
|
509
|
+
["clientRevision", CLIENT_ERROR_REVISION_PATTERN]
|
|
474
510
|
]);
|
|
475
511
|
var PUBLIC_CHANNEL_A_OPERATIONS = /* @__PURE__ */ new Set([
|
|
476
512
|
"fs.list",
|
|
@@ -527,6 +563,7 @@ var PUBLIC_TELEMETRY_ERROR_CLASSES = /* @__PURE__ */ new Set([
|
|
|
527
563
|
"GitCredentialRenewalOperationError",
|
|
528
564
|
"HostExportOperationError",
|
|
529
565
|
"HttpOperationError",
|
|
566
|
+
"KnowledgeIndexOperationError",
|
|
530
567
|
"McpLifecycleError",
|
|
531
568
|
"McpOperationError",
|
|
532
569
|
"MemoryEmbeddingOperationError",
|
|
@@ -575,6 +612,11 @@ var PUBLIC_TELEMETRY_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
|
575
612
|
"idempotency_conflict",
|
|
576
613
|
"incompatible_exposed_ports",
|
|
577
614
|
"internal_error",
|
|
615
|
+
"knowledge_index_defer_failed",
|
|
616
|
+
"knowledge_index_embedding_failed",
|
|
617
|
+
"knowledge_index_failed",
|
|
618
|
+
"knowledge_index_persistence_failed",
|
|
619
|
+
"knowledge_index_usage_limit_reached",
|
|
578
620
|
"limit_exceeded",
|
|
579
621
|
"mcp_close_failed",
|
|
580
622
|
"mcp_connect_failed",
|
|
@@ -1387,6 +1429,7 @@ function projectPublicTelemetryAttributes(attributes) {
|
|
|
1387
1429
|
...projectPublicChannelADiagnosticAttributes(attributes),
|
|
1388
1430
|
...projectApiFatalDiagnosticAttributes(attributes),
|
|
1389
1431
|
...projectSnapshotDiagnosticAttributes(attributes),
|
|
1432
|
+
...projectKnowledgeIndexDiagnosticAttributes(attributes),
|
|
1390
1433
|
...projectPublicDiagnosticAttributes(attributes)
|
|
1391
1434
|
};
|
|
1392
1435
|
}
|
|
@@ -1476,6 +1519,11 @@ function projectSnapshotDiagnosticAttributes(attributes) {
|
|
|
1476
1519
|
projected.leaseEpoch = epoch;
|
|
1477
1520
|
return projected;
|
|
1478
1521
|
}
|
|
1522
|
+
function projectKnowledgeIndexDiagnosticAttributes(attributes) {
|
|
1523
|
+
if (attributes.errorClass !== "KnowledgeIndexOperationError") return {};
|
|
1524
|
+
const sqlState = attributes.sqlState;
|
|
1525
|
+
return typeof sqlState === "string" && /^[0-9A-Z]{5}$/.test(sqlState) ? { sqlState } : {};
|
|
1526
|
+
}
|
|
1479
1527
|
function projectPublicDiagnosticAttributes(attributes) {
|
|
1480
1528
|
const errorClass = attributes.errorClass;
|
|
1481
1529
|
const errorCode = attributes.errorCode;
|
|
@@ -1573,6 +1621,7 @@ export {
|
|
|
1573
1621
|
Observability,
|
|
1574
1622
|
TENANCY_COMPATIBILITY_LANES,
|
|
1575
1623
|
admissionTraceContext,
|
|
1624
|
+
createLogThrottle,
|
|
1576
1625
|
createObservability,
|
|
1577
1626
|
currentTraceContext,
|
|
1578
1627
|
interactionAuthMetricObserver,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/trace-context.ts","../src/export-queue.ts","../src/failure-diagnostic.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { collectDefaultMetrics, Counter, Gauge, Histogram, Registry } from \"prom-client\";\nimport { SandboxBackend } from \"@opengeni/contracts\";\nimport {\n currentTraceContext,\n validTraceContext,\n admissionTraceContext,\n type TraceContext,\n} from \"./trace-context\";\nimport { ExportQueue } from \"./export-queue\";\nimport { failureDiagnostic, type FailureDiagnosticInput } from \"./failure-diagnostic\";\nexport type { FailureDiagnosticInput } from \"./failure-diagnostic\";\nexport {\n currentTraceContext,\n withTraceContext,\n parseTraceparent,\n traceparent,\n admissionTraceContext,\n linkCurrentSpanToAdmission,\n type TraceContext,\n} from \"./trace-context\";\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 /** Explicit restricted OTLP logs destination; never falls back to the public exporter. */\n observabilityDiagnosticsEndpoint?: string | undefined;\n observabilityDiagnosticsHeaders?: string | undefined;\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 addLink?: (context: TraceContext) => void;\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/** Content-free lookup key for a worker execution attempt, never a metric label.\n * Operators derive it from authorized session/attempt records to find a trace\n * without publishing raw tenancy or conversation identifiers to telemetry. */\nexport function turnExecutionTelemetryKey(\n workspaceId: string,\n sessionId: string,\n attemptId: string,\n): string {\n return `turn_${createHash(\"sha256\")\n .update(\"opengeni:turn-execution-telemetry:v1\\0\")\n .update(workspaceId)\n .update(\"\\0\")\n .update(sessionId)\n .update(\"\\0\")\n .update(attemptId)\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 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-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 materializationFailureReason?: string;\n};\n\nconst MATERIALIZATION_FAILURE_REASONS = new Set([\n \"path_not_visible\",\n \"command_failed\",\n \"command_pending\",\n \"invalid_response\",\n \"command_error\",\n]);\nconst MATERIALIZATION_FAILURE_METRIC = {\n name: \"opengeni_sandbox_materialization_verification_failures_total\",\n help: \"Sandbox destination visibility-check failures by bounded reason; exact command evidence is retained in the session failure event.\",\n} as const;\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 spanBatch: unknown[] = [];\n private spanBatchScheduled = false;\n private readonly diagnosticQueue = new ExportQueue((outcome) => {\n this.incrementCounter({\n name: \"opengeni_diagnostic_exports_total\",\n help: \"Protected diagnostic export outcomes.\",\n labels: { outcome },\n });\n });\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 exportQueue = new ExportQueue((outcome) => {\n this.incrementCounter({\n name: \"opengeni_telemetry_exports_total\",\n help: \"Bounded telemetry export outcomes.\",\n labels: { outcome },\n });\n if (outcome === \"failed\")\n this.warn(\"OTLP span export failed\", {\n errorClass: \"TelemetryExportError\",\n errorCode: \"otlp_export_failed\",\n origin: \"observability\",\n });\n }, 8);\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 if ([\"worker\", \"worker-control\", \"worker-turn\", \"api\"].includes(options.component)) {\n // Publish the finite series at startup so a first failure has a zero\n // baseline and healthy zeroes differ from a missing instrumentation path.\n for (const backend of [...SANDBOX_OPERATION_BACKENDS, \"unknown\"]) {\n for (const reason of [...MATERIALIZATION_FAILURE_REASONS, \"unknown\"]) {\n this.incrementCounter({\n ...MATERIALIZATION_FAILURE_METRIC,\n labels: { backend, reason },\n amount: 0,\n });\n }\n }\n }\n if (options.component === \"worker\" || options.component === \"worker-control\") {\n for (const outcome of WORKFLOW_WAKE_OUTCOMES) {\n this.incrementCounter({ ...WORKFLOW_WAKE_METRIC, labels: { outcome }, amount: 0 });\n }\n for (const reason of [...WORKFLOW_WAKE_ADMISSION_BLOCKERS, \"unknown\"]) {\n this.incrementCounter({ ...WORKFLOW_WAKE_BLOCKER_METRIC, labels: { reason }, amount: 0 });\n }\n }\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 context = currentTraceContext();\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 ...(context ? { traceId: context.traceId, spanId: context.spanId } : {}),\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(\n name: string,\n attributes: Attributes = {},\n options: { parent?: TraceContext | null; links?: TraceContext[]; startTimeMs?: number } = {},\n ): Span {\n const parent =\n options.parent === null\n ? undefined\n : validTraceContext(options.parent ?? currentTraceContext());\n const links = (options.links ?? []).slice(0, 8).flatMap((link) => {\n const valid = validTraceContext(link);\n return valid ? [valid] : [];\n });\n const traceId = parent?.traceId ?? randomHex(16);\n const spanId = randomHex(8);\n const now = this.now();\n const startMs = Number.isFinite(options.startTimeMs)\n ? Math.min(now, Math.max(0, options.startTimeMs!))\n : now;\n let ended = false;\n return {\n traceId,\n spanId,\n addLink: (context) => {\n const valid = validTraceContext(context);\n if (\n !ended &&\n valid &&\n links.length < 8 &&\n !links.some((link) => link.traceId === valid.traceId && link.spanId === valid.spanId)\n )\n links.push(valid);\n },\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 ...(parent ? { parentSpanId: parent.spanId } : {}),\n links,\n name: boundedOtlpString(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 /** Emit a content-free anchor after successful, non-replayed admission. */\n recordAdmissionTrace(eventId: string): void {\n const identity = admissionTraceContext(eventId);\n if (!identity) return;\n const current = currentTraceContext();\n const now = this.now();\n this.exportSpan({\n ...identity,\n name: \"api.turn.admitted\",\n startMs: now,\n endMs: now,\n attributes: {},\n links: current ? [current] : [],\n });\n }\n\n /** Emit a closed protected record independently of application persistence. */\n recordFailureDiagnostic(input: FailureDiagnosticInput): string {\n const record = failureDiagnostic(input, this.settings.deploymentRevision);\n const endpoint = this.settings.observabilityDiagnosticsEndpoint;\n if (!endpoint) {\n this.incrementCounter({\n name: \"opengeni_diagnostic_exports_total\",\n help: \"Protected diagnostic export outcomes.\",\n labels: { outcome: \"disabled\" },\n });\n return record.diagnosticId;\n }\n const context = currentTraceContext();\n const body = {\n resourceLogs: [\n {\n resource: { attributes: otlpAttributes(this.resourceAttributes) },\n scopeLogs: [\n {\n scope: { name: \"@opengeni/observability/diagnostics\", version: \"1\" },\n logRecords: [\n {\n timeUnixNano: millisToNanos(this.now()),\n severityNumber: 17,\n severityText: \"ERROR\",\n ...(context ? { traceId: context.traceId, spanId: context.spanId } : {}),\n body: { stringValue: JSON.stringify(record) },\n },\n ],\n },\n ],\n },\n ],\n };\n this.diagnosticQueue.enqueue(() =>\n this.exporter(\n `${endpoint.replace(/\\/$/, \"\")}/v1/logs`,\n body,\n parseHeaders(this.settings.observabilityDiagnosticsHeaders ?? \"\"),\n ),\n );\n return record.diagnosticId;\n }\n\n /** Best-effort bounded drain, including when a custom transport never settles. */\n async flush(timeoutMs = 1_000): Promise<void> {\n this.submitSpanBatch();\n await Promise.all([this.exportQueue.flush(timeoutMs), this.diagnosticQueue.flush(timeoutMs)]);\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 parentSpanId?: string;\n links: TraceContext[];\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 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 ...(span.parentSpanId ? { parentSpanId: span.parentSpanId } : {}),\n links: span.links,\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 this.spanBatch.push(body.resourceSpans[0]);\n if (!this.spanBatchScheduled) {\n this.spanBatchScheduled = true;\n queueMicrotask(() => {\n this.spanBatchScheduled = false;\n this.submitSpanBatch();\n });\n }\n if (this.spanBatch.length >= 32) this.submitSpanBatch();\n }\n\n private submitSpanBatch(): void {\n if (!this.spanBatch.length || !this.settings.observabilityOtlpEndpoint) return;\n const resourceSpans = this.spanBatch;\n this.spanBatch = [];\n const endpoint = `${this.settings.observabilityOtlpEndpoint.replace(/\\/$/, \"\")}/v1/traces`;\n this.exportQueue.enqueue(() =>\n this.exporter(\n endpoint,\n { resourceSpans },\n parseHeaders(this.settings.observabilityOtlpHeaders),\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 if (\n op === \"materializeEntry\" &&\n observation.outcome === \"failed\" &&\n observation.materializationFailureReason\n ) {\n const reason = MATERIALIZATION_FAILURE_REASONS.has(observation.materializationFailureReason)\n ? observation.materializationFailureReason\n : \"unknown\";\n observability.incrementCounter({\n ...MATERIALIZATION_FAILURE_METRIC,\n labels: { backend, reason },\n });\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\n/** Capture waits remain separate from physical provider-call accounting. */\nexport function sandboxCaptureWaitMetricObserver(observability: Observability) {\n return (observation: {\n backend: string;\n op: string;\n outcome: \"ok\" | \"failed\";\n durationMs: number;\n captureWaitStage: \"admission\" | \"provider\";\n }): void => {\n const stage = observation.captureWaitStage;\n if (stage !== \"admission\" && stage !== \"provider\") return;\n if (!Number.isFinite(observation.durationMs) || observation.durationMs < 0) return;\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 const outcome = observation.outcome === \"ok\" ? \"completed\" : \"failed\";\n try {\n observability.observeHistogram({\n name: \"opengeni_sandbox_capture_wait_duration_seconds\",\n help: \"Workspace capture gate wait duration across every routed operation, not only startup.\",\n labels: { backend, op, stage, outcome },\n value: observation.durationMs / 1_000,\n });\n observability\n .startSpan(\n `sandbox.capture_wait.${stage}`,\n { backend, outcome },\n {\n startTimeMs: Date.now() - observation.durationMs,\n },\n )\n .end({ ...(outcome === \"failed\" ? { error: true } : {}) });\n } catch {\n // Diagnostics never alter capture admission or physical settlement.\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\nconst WORKFLOW_WAKE_ADMISSION_BLOCKERS = new Set([\n \"pending_agent_steer\",\n \"pending_prompt_turn\",\n \"pending_quiescence\",\n \"pending_machine_input\",\n \"pending_input_wait\",\n]);\nconst WORKFLOW_WAKE_OUTCOMES = [\n \"signal_accepted\",\n \"acknowledged\",\n \"pending_admission\",\n \"unconfirmed\",\n \"failed\",\n] as const;\nconst WORKFLOW_WAKE_METRIC = {\n name: \"opengeni_session_workflow_wake_observations_total\",\n help: \"Workflow wake dispatch observations; signal acceptance overlaps with admission outcomes, and retries are counted again.\",\n};\nconst WORKFLOW_WAKE_BLOCKER_METRIC = {\n name: \"opengeni_session_workflow_wake_admission_blockers_total\",\n help: \"Workflow wake dispatch attempts awaiting durable admission, by bounded blocker; repeated revisions count again.\",\n};\n\n/** Dispatcher observations count attempts, including repeated observations of\n * the same revision. Transport acceptance is never an admission receipt. */\nexport function recordWorkflowWakeReconciliation(\n observability: Observability,\n result: {\n signaled: number;\n delivered: number;\n pendingAdmission: number;\n unconfirmed: number;\n failed: number;\n pendingAdmissionBlockers: Record<string, number | undefined>;\n },\n): void {\n const count = (value: number | undefined) =>\n typeof value === \"number\" && Number.isSafeInteger(value) && value >= 0 ? value : 0;\n try {\n for (const [outcome, amount] of [\n [\"signal_accepted\", result.signaled],\n [\"acknowledged\", result.delivered],\n [\"pending_admission\", result.pendingAdmission],\n [\"unconfirmed\", result.unconfirmed],\n [\"failed\", result.failed],\n ] as const) {\n observability.incrementCounter({\n ...WORKFLOW_WAKE_METRIC,\n labels: { outcome },\n amount: count(amount),\n });\n if (count(amount) > 0) {\n // Use the reviewed public telemetry vocabulary. Arbitrary aggregate\n // property names are intentionally omitted by the external sink.\n observability.info(\"Session workflow wake dispatch observed\", {\n surface: \"session_workflow_wake\",\n outcome,\n attempts: count(amount),\n });\n }\n }\n for (const [blocker, amount] of Object.entries(result.pendingAdmissionBlockers)) {\n if (count(amount) === 0) continue;\n const reason = boundedMetricEnum(WORKFLOW_WAKE_ADMISSION_BLOCKERS, blocker);\n observability.incrementCounter({\n ...WORKFLOW_WAKE_BLOCKER_METRIC,\n labels: { reason },\n amount: count(amount),\n });\n observability.info(\"Session workflow wake admission pending\", {\n surface: \"session_workflow_wake\",\n outcome: \"pending_admission\",\n reason,\n attempts: count(amount),\n });\n }\n } catch {\n recordObserverFailure(observability, \"session_workflow_wake\");\n }\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} check 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 ...projectSnapshotDiagnosticAttributes(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 projectSnapshotDiagnosticAttributes(attributes: Attributes): Attributes {\n if (attributes.errorClass !== \"SnapshotOperationError\") return {};\n const projected: Attributes = {};\n const causeName = attributes.causeName;\n if (\n typeof causeName === \"string\" &&\n [\"SnapshotTimeoutError\", \"SandboxProviderCaptureTimeoutError\", \"SandboxProviderError\"].includes(\n causeName,\n )\n )\n projected.causeName = causeName;\n const name = attributes.providerErrorName;\n if (\n typeof name === \"string\" &&\n [\n \"ClientError\",\n \"TimeoutError\",\n \"ConnectionError\",\n \"AuthError\",\n \"NotFoundError\",\n \"InvalidError\",\n \"RemoteError\",\n \"AbortError\",\n ].includes(name)\n )\n projected.providerErrorName = name;\n const grpc = attributes.providerGrpcCode;\n if (\n name === \"ClientError\" &&\n typeof grpc === \"number\" &&\n Number.isInteger(grpc) &&\n grpc >= 0 &&\n grpc <= 16\n )\n projected.providerGrpcCode = grpc;\n const http = attributes.providerHttpStatus;\n if (typeof http === \"number\" && Number.isInteger(http) && http >= 100 && http <= 599)\n projected.providerHttpStatus = http;\n if (typeof attributes.providerRetryable === \"boolean\")\n projected.providerRetryable = attributes.providerRetryable;\n const leaseKey = attributes.sandboxLeaseKey;\n if (typeof leaseKey === \"string\" && /^slk_[0-9a-f]{32}$/.test(leaseKey))\n projected.sandboxLeaseKey = leaseKey;\n const epoch = attributes.leaseEpoch;\n if (typeof epoch === \"number\" && Number.isSafeInteger(epoch) && epoch >= 0)\n projected.leaseEpoch = epoch;\n return projected;\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 signal: AbortSignal.timeout(1_000),\n });\n if (!response.ok) {\n throw new Error(`OTLP endpoint returned HTTP ${response.status}`);\n }\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\nimport { createHash } from \"node:crypto\";\n\n/** W3C-compatible identity only: never propagate baggage or user attributes. */\nexport type TraceContext = { traceId: string; spanId: string };\ntype ActiveContext = TraceContext & { addLink?: ((link: TraceContext) => void) | undefined };\nconst storage = new AsyncLocalStorage<ActiveContext | undefined>();\n\nfunction ownData(value: unknown, key: string): unknown {\n if (typeof value !== \"object\" || value === null) return undefined;\n try {\n const descriptor = Object.getOwnPropertyDescriptor(value, key);\n return descriptor && \"value\" in descriptor ? descriptor.value : undefined;\n } catch {\n return undefined;\n }\n}\n\nexport function validTraceContext(value: unknown): TraceContext | undefined {\n // Snapshot primitive own data once. Never invoke getters, coercion or toJSON.\n const traceId = ownData(value, \"traceId\");\n const spanId = ownData(value, \"spanId\");\n if (typeof traceId !== \"string\" || typeof spanId !== \"string\") return undefined;\n if (!/^[0-9a-f]{32}$/.test(traceId) || /^0+$/.test(traceId)) return undefined;\n if (!/^[0-9a-f]{16}$/.test(spanId) || /^0+$/.test(spanId)) return undefined;\n return { traceId, spanId };\n}\n\nexport function currentTraceContext(): TraceContext | undefined {\n return validTraceContext(storage.getStore());\n}\n\n/** Scoped run, never enterWith: interleaved requests cannot inherit each other's spans. */\nexport function withTraceContext<T>(context: ActiveContext | undefined, run: () => T): T {\n const valid = validTraceContext(context);\n const addLink = ownData(context, \"addLink\");\n return storage.run(\n valid\n ? {\n ...valid,\n addLink:\n typeof addLink === \"function\" ? (addLink as ActiveContext[\"addLink\"]) : undefined,\n }\n : undefined,\n run,\n );\n}\n\n/** Stable identity of an actually emitted admission anchor, not session ancestry. */\nexport function admissionTraceContext(eventId: string): TraceContext | undefined {\n if (\n typeof eventId !== \"string\" ||\n !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(eventId)\n )\n return undefined;\n const digest = createHash(\"sha256\")\n .update(\"opengeni:accepted-event-trace:v1\\0\")\n .update(eventId.toLowerCase())\n .digest(\"hex\");\n return validTraceContext({ traceId: digest.slice(0, 32), spanId: digest.slice(32, 48) });\n}\n\nexport function linkCurrentSpanToAdmission(eventId: string): void {\n const link = admissionTraceContext(eventId);\n if (link) storage.getStore()?.addLink?.(link);\n}\n\n/** Remote context must be admitted by the caller's trust boundary before use. */\nexport function parseTraceparent(value: string | undefined): TraceContext | undefined {\n if (typeof value !== \"string\") return undefined;\n const match = /^00-([0-9a-f]{32})-([0-9a-f]{16})-[0-9a-f]{2}$/.exec(value ?? \"\");\n return match ? validTraceContext({ traceId: match[1]!, spanId: match[2]! }) : undefined;\n}\n\nexport function traceparent(context: TraceContext): string | undefined {\n const valid = validTraceContext(context);\n return valid ? `00-${valid.traceId}-${valid.spanId}-01` : undefined;\n}\n","/** One bounded lane per observer. A hung custom transport holds one slot, not an unbounded retry fanout. */\nexport class ExportQueue {\n private readonly queue: Array<() => Promise<void>> = [];\n private running: Promise<void> | undefined;\n constructor(\n private readonly observer: (outcome: \"exported\" | \"retried\" | \"failed\" | \"dropped\") => void,\n private readonly capacity = 256,\n ) {}\n\n private observe(outcome: \"exported\" | \"retried\" | \"failed\" | \"dropped\"): void {\n try {\n this.observer(outcome);\n } catch {\n /* Health reporting must not retry a successful export. */\n }\n }\n\n enqueue(send: () => Promise<void>): void {\n if (this.queue.length >= this.capacity) {\n this.observe(\"dropped\");\n return;\n }\n this.queue.push(send);\n this.start();\n }\n\n private start(): void {\n if (!this.running) {\n this.running = Promise.resolve()\n .then(() => this.drain())\n .finally(() => {\n this.running = undefined;\n if (this.queue.length) this.start();\n });\n }\n }\n\n private async drain(): Promise<void> {\n while (this.queue.length) {\n const send = this.queue.shift()!;\n for (let attempt = 0; attempt < 3; attempt++) {\n try {\n await send();\n this.observe(\"exported\");\n break;\n } catch {\n if (attempt === 2) this.observe(\"failed\");\n else {\n this.observe(\"retried\");\n await new Promise((resolve) => setTimeout(resolve, 25 * 2 ** attempt));\n }\n }\n }\n }\n }\n\n async flush(timeoutMs = 1_000): Promise<void> {\n if (!this.running) return;\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n await Promise.race([\n this.running,\n new Promise<void>((resolve) => {\n timer = setTimeout(\n resolve,\n Number.isFinite(timeoutMs) ? Math.max(1, Math.min(timeoutMs, 5_000)) : 1_000,\n );\n }),\n ]);\n } finally {\n clearTimeout(timer);\n }\n }\n}\n","import { createHash, randomUUID } from \"node:crypto\";\nimport { SessionEventType } from \"@opengeni/contracts\";\n\nconst CODES = [\n \"api_startup_failed\",\n \"api_unhandled_rejection\",\n \"api_uncaught_exception\",\n \"db_deadlock\",\n \"db_serialization_failure\",\n \"db_failure\",\n \"retained_process_fenced\",\n \"retained_process_proof_failed\",\n] as const;\nconst STAGES = [\n \"startup\",\n \"running\",\n \"session_events.append_generic\",\n \"session_events.append_for_turn_attempt\",\n \"preclaim\",\n \"session_attempts.claim\",\n \"failure_settlement\",\n \"sandbox_retained_processes.proof\",\n] as const;\nconst RETRIES = [\"not_retryable\", \"exhausted\", \"unknown\"] as const;\n// Reviewed schema names, never a syntactic allowlist for arbitrary driver strings.\nconst CONSTRAINTS = new Set([\n \"session_events_workspace_account_fk\",\n \"session_events_turn_association_check\",\n \"session_events_payload_bytes_check\",\n \"session_events_type_bytes_check\",\n \"session_events_duplicate_classification_check\",\n \"sandbox_retained_processes_reconcile_proof_check\",\n \"sandbox_retained_processes_reconcile_claim_check\",\n \"sandbox_retained_processes_settlement_check\",\n]);\nconst ERROR_NAMES = new Set([\n \"Error\",\n \"TypeError\",\n \"RangeError\",\n \"AggregateError\",\n \"PostgresError\",\n \"DrizzleQueryError\",\n \"SessionEventPersistenceError\",\n \"SandboxWorkspaceMutationFencedError\",\n]);\n\n// Human-reviewed code locations, not a regex permission to publish any path.\nexport const DIAGNOSTIC_SOURCE_FILES = [\n \"apps/api/src/index.ts\",\n \"apps/api/src/app.ts\",\n \"apps/api/src/fatal-process-boundary.ts\",\n \"apps/api/dist/process/index.js\",\n \"apps/worker/src/activities/agent-turn/run.ts\",\n \"apps/worker/src/activities/agent-turn/claim.ts\",\n \"apps/worker/src/activities/agent-turn/failure-settlement.ts\",\n \"apps/worker/src/activities/sandbox-lease.ts\",\n \"apps/worker/dist/process/index.js\",\n \"packages/db/src/index.ts\",\n \"packages/db/src/persistence-errors.ts\",\n \"packages/storage/src/index.ts\",\n \"packages/observability/src/index.ts\",\n] as const;\n\nexport const DIAGNOSTIC_POSTGRES_FUNCTIONS = [\"admit_session_attempt_personal_resources\"] as const;\n\nfunction reviewedSource(location: string): string | undefined {\n // Match an exact reviewed suffix; discard the host/deployment path entirely.\n return DIAGNOSTIC_SOURCE_FILES.find((file) => location === file || location.endsWith(`/${file}`));\n}\n\nfunction postgresContext(error: unknown): Array<{ functionName: string; line: number }> {\n if (errorKind(error) !== \"PostgresError\") return [];\n const where = own(error, \"where\");\n if (typeof where !== \"string\") return [];\n return where\n .slice(0, 8_192)\n .split(\"\\n\")\n .slice(0, 16)\n .flatMap((value) => {\n const match = /^PL\\/pgSQL function (?:public\\.)?([a-z_]+)\\([^\\n]*\\) line (\\d{1,7}) at /.exec(\n value,\n );\n if (!match || !DIAGNOSTIC_POSTGRES_FUNCTIONS.some((name) => name === match[1])) return [];\n return [{ functionName: match[1]!, line: Number(match[2]) }];\n })\n .slice(0, 8);\n}\n\nexport type FailureDiagnosticInput = {\n code: (typeof CODES)[number];\n stage: (typeof STAGES)[number];\n retryDecision?: (typeof RETRIES)[number];\n error: unknown;\n attemptId?: string;\n sessionId?: string;\n processId?: string;\n turnId?: string;\n attempts?: number;\n sqlState?: string | null;\n constraint?: string;\n eventTypes?: readonly string[];\n};\n\nfunction own(value: unknown, key: string): unknown {\n try {\n if (!value || typeof value !== \"object\") return undefined;\n const descriptor = Object.getOwnPropertyDescriptor(value, key);\n return descriptor && \"value\" in descriptor ? descriptor.value : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction errorKind(error: unknown): string {\n const name = own(error, \"name\");\n if (typeof name === \"string\" && ERROR_NAMES.has(name)) return name;\n try {\n const prototype = Object.getPrototypeOf(error);\n if (prototype === TypeError.prototype) return \"TypeError\";\n if (prototype === RangeError.prototype) return \"RangeError\";\n if (prototype === AggregateError.prototype) return \"AggregateError\";\n } catch {\n /* Untrusted proxies do not contribute type information. */\n }\n return \"Error\";\n}\n\n/** No arbitrary property reads, Error.toJSON, messages, SQL, parameters or function names. */\nexport function failureDiagnostic(input: FailureDiagnosticInput, revision?: string) {\n const causes: Array<{\n kind: string;\n frames: Array<{ locationHash: string; source?: string; line: number; column: number }>;\n }> = [];\n const pgContext: Array<{ functionName: string; line: number }> = [];\n const seen = new Set<unknown>();\n let error = input.error;\n while (error && typeof error === \"object\" && !seen.has(error) && causes.length < 4) {\n seen.add(error);\n pgContext.push(...postgresContext(error).slice(0, 8 - pgContext.length));\n const stack = own(error, \"stack\");\n const frames =\n typeof stack === \"string\"\n ? stack\n .slice(0, 16_384)\n .split(\"\\n\")\n .slice(1, 33)\n .flatMap((frame) => {\n const match = /(?:\\(|\\s)([^\\s()]+):(\\d{1,7}):(\\d{1,7})\\)?$/.exec(frame);\n if (!match) return [];\n // Even a path/function can contain a credential. Keep source-location\n // fingerprints plus line/column, not untrusted textual stack bytes.\n return [\n {\n locationHash: createHash(\"sha256\").update(match[1]!).digest(\"hex\"),\n ...(reviewedSource(match[1]!) ? { source: reviewedSource(match[1]!)! } : {}),\n line: Number(match[2]),\n column: Number(match[3]),\n },\n ];\n })\n : [];\n causes.push({\n kind: errorKind(error),\n frames,\n });\n error = own(error, \"cause\");\n }\n const uuid = (value: unknown) =>\n typeof value === \"string\" &&\n /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value)\n ? value\n : undefined;\n return {\n schema: \"opengeni.failure-diagnostic.v1\",\n diagnosticId: randomUUID(),\n code: CODES.includes(input.code) ? input.code : \"db_failure\",\n stage: STAGES.includes(input.stage) ? input.stage : \"failure_settlement\",\n retryDecision:\n input.retryDecision && RETRIES.includes(input.retryDecision)\n ? input.retryDecision\n : \"unknown\",\n attemptId: uuid(input.attemptId),\n sessionId: uuid(input.sessionId),\n processId: uuid(input.processId),\n turnId: uuid(input.turnId),\n attempts:\n Number.isSafeInteger(input.attempts) && input.attempts! >= 0 && input.attempts! <= 1_000_000\n ? input.attempts\n : undefined,\n sqlState:\n typeof input.sqlState === \"string\" && /^[0-9A-Z]{5}$/.test(input.sqlState)\n ? input.sqlState\n : undefined,\n constraint:\n input.constraint && CONSTRAINTS.has(input.constraint) ? input.constraint : undefined,\n deploymentRevision: revision && /^[0-9a-f]{40}$/.test(revision) ? revision : undefined,\n causes,\n postgresContext: pgContext,\n eventTypes: (input.eventTypes ?? [])\n .slice(0, 32)\n .filter((type) => SessionEventType.safeParse(type).success),\n };\n}\n"],"mappings":"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","names":["createHash","createHash","createHash"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/trace-context.ts","../src/export-queue.ts","../src/failure-diagnostic.ts","../src/log-throttle.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { collectDefaultMetrics, Counter, Gauge, Histogram, Registry } from \"prom-client\";\nimport { SandboxBackend } from \"@opengeni/contracts\";\nimport {\n CLIENT_ERROR_REVISION_PATTERN,\n CLIENT_ERROR_ROUTE_PATTERN,\n} from \"@opengeni/contracts/client-error-report\";\nimport {\n currentTraceContext,\n validTraceContext,\n admissionTraceContext,\n type TraceContext,\n} from \"./trace-context\";\nimport { ExportQueue } from \"./export-queue\";\nimport { failureDiagnostic, type FailureDiagnosticInput } from \"./failure-diagnostic\";\nexport type { FailureDiagnosticInput } from \"./failure-diagnostic\";\nexport { createLogThrottle, type LogThrottle } from \"./log-throttle\";\nexport {\n currentTraceContext,\n withTraceContext,\n parseTraceparent,\n traceparent,\n admissionTraceContext,\n linkCurrentSpanToAdmission,\n type TraceContext,\n} from \"./trace-context\";\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 /** Explicit restricted OTLP logs destination; never falls back to the public exporter. */\n observabilityDiagnosticsEndpoint?: string | undefined;\n observabilityDiagnosticsHeaders?: string | undefined;\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 addLink?: (context: TraceContext) => void;\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/** Content-free lookup key for a worker execution attempt, never a metric label.\n * Operators derive it from authorized session/attempt records to find a trace\n * without publishing raw tenancy or conversation identifiers to telemetry. */\nexport function turnExecutionTelemetryKey(\n workspaceId: string,\n sessionId: string,\n attemptId: string,\n): string {\n return `turn_${createHash(\"sha256\")\n .update(\"opengeni:turn-execution-telemetry:v1\\0\")\n .update(workspaceId)\n .update(\"\\0\")\n .update(sessionId)\n .update(\"\\0\")\n .update(attemptId)\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 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 \"suppressedCount\",\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 // Web error beacon: a route PATTERN of lowercase literal and `$param`\n // segments (never a concrete path or id) and the bundle revision token, in\n // the exact wire grammar the API route admits.\n [\"clientRoute\", CLIENT_ERROR_ROUTE_PATTERN],\n [\"clientRevision\", CLIENT_ERROR_REVISION_PATTERN],\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 \"KnowledgeIndexOperationError\",\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 \"knowledge_index_defer_failed\",\n \"knowledge_index_embedding_failed\",\n \"knowledge_index_failed\",\n \"knowledge_index_persistence_failed\",\n \"knowledge_index_usage_limit_reached\",\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-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 materializationFailureReason?: string;\n};\n\nconst MATERIALIZATION_FAILURE_REASONS = new Set([\n \"path_not_visible\",\n \"command_failed\",\n \"command_pending\",\n \"invalid_response\",\n \"command_error\",\n]);\nconst MATERIALIZATION_FAILURE_METRIC = {\n name: \"opengeni_sandbox_materialization_verification_failures_total\",\n help: \"Sandbox destination visibility-check failures by bounded reason; exact command evidence is retained in the session failure event.\",\n} as const;\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 spanBatch: unknown[] = [];\n private spanBatchScheduled = false;\n private readonly diagnosticQueue = new ExportQueue((outcome) => {\n this.incrementCounter({\n name: \"opengeni_diagnostic_exports_total\",\n help: \"Protected diagnostic export outcomes.\",\n labels: { outcome },\n });\n });\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 exportQueue = new ExportQueue((outcome) => {\n this.incrementCounter({\n name: \"opengeni_telemetry_exports_total\",\n help: \"Bounded telemetry export outcomes.\",\n labels: { outcome },\n });\n if (outcome === \"failed\")\n this.warn(\"OTLP span export failed\", {\n errorClass: \"TelemetryExportError\",\n errorCode: \"otlp_export_failed\",\n origin: \"observability\",\n });\n }, 8);\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 if ([\"worker\", \"worker-control\", \"worker-turn\", \"api\"].includes(options.component)) {\n // Publish the finite series at startup so a first failure has a zero\n // baseline and healthy zeroes differ from a missing instrumentation path.\n for (const backend of [...SANDBOX_OPERATION_BACKENDS, \"unknown\"]) {\n for (const reason of [...MATERIALIZATION_FAILURE_REASONS, \"unknown\"]) {\n this.incrementCounter({\n ...MATERIALIZATION_FAILURE_METRIC,\n labels: { backend, reason },\n amount: 0,\n });\n }\n }\n }\n if (options.component === \"worker\" || options.component === \"worker-control\") {\n for (const outcome of WORKFLOW_WAKE_OUTCOMES) {\n this.incrementCounter({ ...WORKFLOW_WAKE_METRIC, labels: { outcome }, amount: 0 });\n }\n for (const reason of [...WORKFLOW_WAKE_ADMISSION_BLOCKERS, \"unknown\"]) {\n this.incrementCounter({ ...WORKFLOW_WAKE_BLOCKER_METRIC, labels: { reason }, amount: 0 });\n }\n }\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 context = currentTraceContext();\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 ...(context ? { traceId: context.traceId, spanId: context.spanId } : {}),\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(\n name: string,\n attributes: Attributes = {},\n options: { parent?: TraceContext | null; links?: TraceContext[]; startTimeMs?: number } = {},\n ): Span {\n const parent =\n options.parent === null\n ? undefined\n : validTraceContext(options.parent ?? currentTraceContext());\n const links = (options.links ?? []).slice(0, 8).flatMap((link) => {\n const valid = validTraceContext(link);\n return valid ? [valid] : [];\n });\n const traceId = parent?.traceId ?? randomHex(16);\n const spanId = randomHex(8);\n const now = this.now();\n const startMs = Number.isFinite(options.startTimeMs)\n ? Math.min(now, Math.max(0, options.startTimeMs!))\n : now;\n let ended = false;\n return {\n traceId,\n spanId,\n addLink: (context) => {\n const valid = validTraceContext(context);\n if (\n !ended &&\n valid &&\n links.length < 8 &&\n !links.some((link) => link.traceId === valid.traceId && link.spanId === valid.spanId)\n )\n links.push(valid);\n },\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 ...(parent ? { parentSpanId: parent.spanId } : {}),\n links,\n name: boundedOtlpString(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 /** Emit a content-free anchor after successful, non-replayed admission. */\n recordAdmissionTrace(eventId: string): void {\n const identity = admissionTraceContext(eventId);\n if (!identity) return;\n const current = currentTraceContext();\n const now = this.now();\n this.exportSpan({\n ...identity,\n name: \"api.turn.admitted\",\n startMs: now,\n endMs: now,\n attributes: {},\n links: current ? [current] : [],\n });\n }\n\n /** Emit a closed protected record independently of application persistence. */\n recordFailureDiagnostic(input: FailureDiagnosticInput): string {\n const record = failureDiagnostic(input, this.settings.deploymentRevision);\n const endpoint = this.settings.observabilityDiagnosticsEndpoint;\n if (!endpoint) {\n this.incrementCounter({\n name: \"opengeni_diagnostic_exports_total\",\n help: \"Protected diagnostic export outcomes.\",\n labels: { outcome: \"disabled\" },\n });\n return record.diagnosticId;\n }\n const context = currentTraceContext();\n const body = {\n resourceLogs: [\n {\n resource: { attributes: otlpAttributes(this.resourceAttributes) },\n scopeLogs: [\n {\n scope: { name: \"@opengeni/observability/diagnostics\", version: \"1\" },\n logRecords: [\n {\n timeUnixNano: millisToNanos(this.now()),\n severityNumber: 17,\n severityText: \"ERROR\",\n ...(context ? { traceId: context.traceId, spanId: context.spanId } : {}),\n body: { stringValue: JSON.stringify(record) },\n },\n ],\n },\n ],\n },\n ],\n };\n this.diagnosticQueue.enqueue(() =>\n this.exporter(\n `${endpoint.replace(/\\/$/, \"\")}/v1/logs`,\n body,\n parseHeaders(this.settings.observabilityDiagnosticsHeaders ?? \"\"),\n ),\n );\n return record.diagnosticId;\n }\n\n /** Best-effort bounded drain, including when a custom transport never settles. */\n async flush(timeoutMs = 1_000): Promise<void> {\n this.submitSpanBatch();\n await Promise.all([this.exportQueue.flush(timeoutMs), this.diagnosticQueue.flush(timeoutMs)]);\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 parentSpanId?: string;\n links: TraceContext[];\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 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 ...(span.parentSpanId ? { parentSpanId: span.parentSpanId } : {}),\n links: span.links,\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 this.spanBatch.push(body.resourceSpans[0]);\n if (!this.spanBatchScheduled) {\n this.spanBatchScheduled = true;\n queueMicrotask(() => {\n this.spanBatchScheduled = false;\n this.submitSpanBatch();\n });\n }\n if (this.spanBatch.length >= 32) this.submitSpanBatch();\n }\n\n private submitSpanBatch(): void {\n if (!this.spanBatch.length || !this.settings.observabilityOtlpEndpoint) return;\n const resourceSpans = this.spanBatch;\n this.spanBatch = [];\n const endpoint = `${this.settings.observabilityOtlpEndpoint.replace(/\\/$/, \"\")}/v1/traces`;\n this.exportQueue.enqueue(() =>\n this.exporter(\n endpoint,\n { resourceSpans },\n parseHeaders(this.settings.observabilityOtlpHeaders),\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 if (\n op === \"materializeEntry\" &&\n observation.outcome === \"failed\" &&\n observation.materializationFailureReason\n ) {\n const reason = MATERIALIZATION_FAILURE_REASONS.has(observation.materializationFailureReason)\n ? observation.materializationFailureReason\n : \"unknown\";\n observability.incrementCounter({\n ...MATERIALIZATION_FAILURE_METRIC,\n labels: { backend, reason },\n });\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\n/** Capture waits remain separate from physical provider-call accounting. */\nexport function sandboxCaptureWaitMetricObserver(observability: Observability) {\n return (observation: {\n backend: string;\n op: string;\n outcome: \"ok\" | \"failed\";\n durationMs: number;\n captureWaitStage: \"admission\" | \"provider\";\n }): void => {\n const stage = observation.captureWaitStage;\n if (stage !== \"admission\" && stage !== \"provider\") return;\n if (!Number.isFinite(observation.durationMs) || observation.durationMs < 0) return;\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 const outcome = observation.outcome === \"ok\" ? \"completed\" : \"failed\";\n try {\n observability.observeHistogram({\n name: \"opengeni_sandbox_capture_wait_duration_seconds\",\n help: \"Workspace capture gate wait duration across every routed operation, not only startup.\",\n labels: { backend, op, stage, outcome },\n value: observation.durationMs / 1_000,\n });\n observability\n .startSpan(\n `sandbox.capture_wait.${stage}`,\n { backend, outcome },\n {\n startTimeMs: Date.now() - observation.durationMs,\n },\n )\n .end({ ...(outcome === \"failed\" ? { error: true } : {}) });\n } catch {\n // Diagnostics never alter capture admission or physical settlement.\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\nconst WORKFLOW_WAKE_ADMISSION_BLOCKERS = new Set([\n \"pending_agent_steer\",\n \"pending_prompt_turn\",\n \"pending_quiescence\",\n \"pending_machine_input\",\n \"pending_input_wait\",\n]);\nconst WORKFLOW_WAKE_OUTCOMES = [\n \"signal_accepted\",\n \"acknowledged\",\n \"pending_admission\",\n \"unconfirmed\",\n \"failed\",\n] as const;\nconst WORKFLOW_WAKE_METRIC = {\n name: \"opengeni_session_workflow_wake_observations_total\",\n help: \"Workflow wake dispatch observations; signal acceptance overlaps with admission outcomes, and retries are counted again.\",\n};\nconst WORKFLOW_WAKE_BLOCKER_METRIC = {\n name: \"opengeni_session_workflow_wake_admission_blockers_total\",\n help: \"Workflow wake dispatch attempts awaiting durable admission, by bounded blocker; repeated revisions count again.\",\n};\n\n/** Dispatcher observations count attempts, including repeated observations of\n * the same revision. Transport acceptance is never an admission receipt. */\nexport function recordWorkflowWakeReconciliation(\n observability: Observability,\n result: {\n signaled: number;\n delivered: number;\n pendingAdmission: number;\n unconfirmed: number;\n failed: number;\n pendingAdmissionBlockers: Record<string, number | undefined>;\n },\n): void {\n const count = (value: number | undefined) =>\n typeof value === \"number\" && Number.isSafeInteger(value) && value >= 0 ? value : 0;\n try {\n for (const [outcome, amount] of [\n [\"signal_accepted\", result.signaled],\n [\"acknowledged\", result.delivered],\n [\"pending_admission\", result.pendingAdmission],\n [\"unconfirmed\", result.unconfirmed],\n [\"failed\", result.failed],\n ] as const) {\n observability.incrementCounter({\n ...WORKFLOW_WAKE_METRIC,\n labels: { outcome },\n amount: count(amount),\n });\n if (count(amount) > 0) {\n // Use the reviewed public telemetry vocabulary. Arbitrary aggregate\n // property names are intentionally omitted by the external sink.\n observability.info(\"Session workflow wake dispatch observed\", {\n surface: \"session_workflow_wake\",\n outcome,\n attempts: count(amount),\n });\n }\n }\n for (const [blocker, amount] of Object.entries(result.pendingAdmissionBlockers)) {\n if (count(amount) === 0) continue;\n const reason = boundedMetricEnum(WORKFLOW_WAKE_ADMISSION_BLOCKERS, blocker);\n observability.incrementCounter({\n ...WORKFLOW_WAKE_BLOCKER_METRIC,\n labels: { reason },\n amount: count(amount),\n });\n observability.info(\"Session workflow wake admission pending\", {\n surface: \"session_workflow_wake\",\n outcome: \"pending_admission\",\n reason,\n attempts: count(amount),\n });\n }\n } catch {\n recordObserverFailure(observability, \"session_workflow_wake\");\n }\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} check 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 ...projectSnapshotDiagnosticAttributes(attributes),\n ...projectKnowledgeIndexDiagnosticAttributes(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 projectSnapshotDiagnosticAttributes(attributes: Attributes): Attributes {\n if (attributes.errorClass !== \"SnapshotOperationError\") return {};\n const projected: Attributes = {};\n const causeName = attributes.causeName;\n if (\n typeof causeName === \"string\" &&\n [\"SnapshotTimeoutError\", \"SandboxProviderCaptureTimeoutError\", \"SandboxProviderError\"].includes(\n causeName,\n )\n )\n projected.causeName = causeName;\n const name = attributes.providerErrorName;\n if (\n typeof name === \"string\" &&\n [\n \"ClientError\",\n \"TimeoutError\",\n \"ConnectionError\",\n \"AuthError\",\n \"NotFoundError\",\n \"InvalidError\",\n \"RemoteError\",\n \"AbortError\",\n ].includes(name)\n )\n projected.providerErrorName = name;\n const grpc = attributes.providerGrpcCode;\n if (\n name === \"ClientError\" &&\n typeof grpc === \"number\" &&\n Number.isInteger(grpc) &&\n grpc >= 0 &&\n grpc <= 16\n )\n projected.providerGrpcCode = grpc;\n const http = attributes.providerHttpStatus;\n if (typeof http === \"number\" && Number.isInteger(http) && http >= 100 && http <= 599)\n projected.providerHttpStatus = http;\n if (typeof attributes.providerRetryable === \"boolean\")\n projected.providerRetryable = attributes.providerRetryable;\n const leaseKey = attributes.sandboxLeaseKey;\n if (typeof leaseKey === \"string\" && /^slk_[0-9a-f]{32}$/.test(leaseKey))\n projected.sandboxLeaseKey = leaseKey;\n const epoch = attributes.leaseEpoch;\n if (typeof epoch === \"number\" && Number.isSafeInteger(epoch) && epoch >= 0)\n projected.leaseEpoch = epoch;\n return projected;\n}\n\nfunction projectKnowledgeIndexDiagnosticAttributes(attributes: Attributes): Attributes {\n if (attributes.errorClass !== \"KnowledgeIndexOperationError\") return {};\n const sqlState = attributes.sqlState;\n // A SQLSTATE is a five-character protocol code, never message or SQL text.\n return typeof sqlState === \"string\" && /^[0-9A-Z]{5}$/.test(sqlState) ? { sqlState } : {};\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 signal: AbortSignal.timeout(1_000),\n });\n if (!response.ok) {\n throw new Error(`OTLP endpoint returned HTTP ${response.status}`);\n }\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\nimport { createHash } from \"node:crypto\";\n\n/** W3C-compatible identity only: never propagate baggage or user attributes. */\nexport type TraceContext = { traceId: string; spanId: string };\ntype ActiveContext = TraceContext & { addLink?: ((link: TraceContext) => void) | undefined };\nconst storage = new AsyncLocalStorage<ActiveContext | undefined>();\n\nfunction ownData(value: unknown, key: string): unknown {\n if (typeof value !== \"object\" || value === null) return undefined;\n try {\n const descriptor = Object.getOwnPropertyDescriptor(value, key);\n return descriptor && \"value\" in descriptor ? descriptor.value : undefined;\n } catch {\n return undefined;\n }\n}\n\nexport function validTraceContext(value: unknown): TraceContext | undefined {\n // Snapshot primitive own data once. Never invoke getters, coercion or toJSON.\n const traceId = ownData(value, \"traceId\");\n const spanId = ownData(value, \"spanId\");\n if (typeof traceId !== \"string\" || typeof spanId !== \"string\") return undefined;\n if (!/^[0-9a-f]{32}$/.test(traceId) || /^0+$/.test(traceId)) return undefined;\n if (!/^[0-9a-f]{16}$/.test(spanId) || /^0+$/.test(spanId)) return undefined;\n return { traceId, spanId };\n}\n\nexport function currentTraceContext(): TraceContext | undefined {\n return validTraceContext(storage.getStore());\n}\n\n/** Scoped run, never enterWith: interleaved requests cannot inherit each other's spans. */\nexport function withTraceContext<T>(context: ActiveContext | undefined, run: () => T): T {\n const valid = validTraceContext(context);\n const addLink = ownData(context, \"addLink\");\n return storage.run(\n valid\n ? {\n ...valid,\n addLink:\n typeof addLink === \"function\" ? (addLink as ActiveContext[\"addLink\"]) : undefined,\n }\n : undefined,\n run,\n );\n}\n\n/** Stable identity of an actually emitted admission anchor, not session ancestry. */\nexport function admissionTraceContext(eventId: string): TraceContext | undefined {\n if (\n typeof eventId !== \"string\" ||\n !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(eventId)\n )\n return undefined;\n const digest = createHash(\"sha256\")\n .update(\"opengeni:accepted-event-trace:v1\\0\")\n .update(eventId.toLowerCase())\n .digest(\"hex\");\n return validTraceContext({ traceId: digest.slice(0, 32), spanId: digest.slice(32, 48) });\n}\n\nexport function linkCurrentSpanToAdmission(eventId: string): void {\n const link = admissionTraceContext(eventId);\n if (link) storage.getStore()?.addLink?.(link);\n}\n\n/** Remote context must be admitted by the caller's trust boundary before use. */\nexport function parseTraceparent(value: string | undefined): TraceContext | undefined {\n if (typeof value !== \"string\") return undefined;\n const match = /^00-([0-9a-f]{32})-([0-9a-f]{16})-[0-9a-f]{2}$/.exec(value ?? \"\");\n return match ? validTraceContext({ traceId: match[1]!, spanId: match[2]! }) : undefined;\n}\n\nexport function traceparent(context: TraceContext): string | undefined {\n const valid = validTraceContext(context);\n return valid ? `00-${valid.traceId}-${valid.spanId}-01` : undefined;\n}\n","/** One bounded lane per observer. A hung custom transport holds one slot, not an unbounded retry fanout. */\nexport class ExportQueue {\n private readonly queue: Array<() => Promise<void>> = [];\n private running: Promise<void> | undefined;\n constructor(\n private readonly observer: (outcome: \"exported\" | \"retried\" | \"failed\" | \"dropped\") => void,\n private readonly capacity = 256,\n ) {}\n\n private observe(outcome: \"exported\" | \"retried\" | \"failed\" | \"dropped\"): void {\n try {\n this.observer(outcome);\n } catch {\n /* Health reporting must not retry a successful export. */\n }\n }\n\n enqueue(send: () => Promise<void>): void {\n if (this.queue.length >= this.capacity) {\n this.observe(\"dropped\");\n return;\n }\n this.queue.push(send);\n this.start();\n }\n\n private start(): void {\n if (!this.running) {\n this.running = Promise.resolve()\n .then(() => this.drain())\n .finally(() => {\n this.running = undefined;\n if (this.queue.length) this.start();\n });\n }\n }\n\n private async drain(): Promise<void> {\n while (this.queue.length) {\n const send = this.queue.shift()!;\n for (let attempt = 0; attempt < 3; attempt++) {\n try {\n await send();\n this.observe(\"exported\");\n break;\n } catch {\n if (attempt === 2) this.observe(\"failed\");\n else {\n this.observe(\"retried\");\n await new Promise((resolve) => setTimeout(resolve, 25 * 2 ** attempt));\n }\n }\n }\n }\n }\n\n async flush(timeoutMs = 1_000): Promise<void> {\n if (!this.running) return;\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n await Promise.race([\n this.running,\n new Promise<void>((resolve) => {\n timer = setTimeout(\n resolve,\n Number.isFinite(timeoutMs) ? Math.max(1, Math.min(timeoutMs, 5_000)) : 1_000,\n );\n }),\n ]);\n } finally {\n clearTimeout(timer);\n }\n }\n}\n","import { createHash, randomUUID } from \"node:crypto\";\nimport { SessionEventType } from \"@opengeni/contracts\";\n\nconst CODES = [\n \"api_startup_failed\",\n \"api_unhandled_rejection\",\n \"api_uncaught_exception\",\n \"db_deadlock\",\n \"db_serialization_failure\",\n \"db_failure\",\n \"retained_process_fenced\",\n \"retained_process_proof_failed\",\n] as const;\nconst STAGES = [\n \"startup\",\n \"running\",\n \"session_events.append_generic\",\n \"session_events.append_for_turn_attempt\",\n \"preclaim\",\n \"session_attempts.claim\",\n \"failure_settlement\",\n \"sandbox_retained_processes.proof\",\n] as const;\nconst RETRIES = [\"not_retryable\", \"exhausted\", \"unknown\"] as const;\n// Reviewed schema names, never a syntactic allowlist for arbitrary driver strings.\nconst CONSTRAINTS = new Set([\n \"session_events_workspace_account_fk\",\n \"session_events_turn_association_check\",\n \"session_events_payload_bytes_check\",\n \"session_events_type_bytes_check\",\n \"session_events_duplicate_classification_check\",\n \"sandbox_retained_processes_reconcile_proof_check\",\n \"sandbox_retained_processes_reconcile_claim_check\",\n \"sandbox_retained_processes_settlement_check\",\n]);\nconst ERROR_NAMES = new Set([\n \"Error\",\n \"TypeError\",\n \"RangeError\",\n \"AggregateError\",\n \"PostgresError\",\n \"DrizzleQueryError\",\n \"SessionEventPersistenceError\",\n \"SandboxWorkspaceMutationFencedError\",\n]);\n\n// Human-reviewed code locations, not a regex permission to publish any path.\nexport const DIAGNOSTIC_SOURCE_FILES = [\n \"apps/api/src/index.ts\",\n \"apps/api/src/app.ts\",\n \"apps/api/src/fatal-process-boundary.ts\",\n \"apps/api/dist/process/index.js\",\n \"apps/worker/src/activities/agent-turn/run.ts\",\n \"apps/worker/src/activities/agent-turn/claim.ts\",\n \"apps/worker/src/activities/agent-turn/failure-settlement.ts\",\n \"apps/worker/src/activities/sandbox-lease.ts\",\n \"apps/worker/dist/process/index.js\",\n \"packages/db/src/index.ts\",\n \"packages/db/src/persistence-errors.ts\",\n \"packages/storage/src/index.ts\",\n \"packages/observability/src/index.ts\",\n] as const;\n\nexport const DIAGNOSTIC_POSTGRES_FUNCTIONS = [\"admit_session_attempt_personal_resources\"] as const;\n\nfunction reviewedSource(location: string): string | undefined {\n // Match an exact reviewed suffix; discard the host/deployment path entirely.\n return DIAGNOSTIC_SOURCE_FILES.find((file) => location === file || location.endsWith(`/${file}`));\n}\n\nfunction postgresContext(error: unknown): Array<{ functionName: string; line: number }> {\n if (errorKind(error) !== \"PostgresError\") return [];\n const where = own(error, \"where\");\n if (typeof where !== \"string\") return [];\n return where\n .slice(0, 8_192)\n .split(\"\\n\")\n .slice(0, 16)\n .flatMap((value) => {\n const match = /^PL\\/pgSQL function (?:public\\.)?([a-z_]+)\\([^\\n]*\\) line (\\d{1,7}) at /.exec(\n value,\n );\n if (!match || !DIAGNOSTIC_POSTGRES_FUNCTIONS.some((name) => name === match[1])) return [];\n return [{ functionName: match[1]!, line: Number(match[2]) }];\n })\n .slice(0, 8);\n}\n\nexport type FailureDiagnosticInput = {\n code: (typeof CODES)[number];\n stage: (typeof STAGES)[number];\n retryDecision?: (typeof RETRIES)[number];\n error: unknown;\n attemptId?: string;\n sessionId?: string;\n processId?: string;\n turnId?: string;\n attempts?: number;\n sqlState?: string | null;\n constraint?: string;\n eventTypes?: readonly string[];\n};\n\nfunction own(value: unknown, key: string): unknown {\n try {\n if (!value || typeof value !== \"object\") return undefined;\n const descriptor = Object.getOwnPropertyDescriptor(value, key);\n return descriptor && \"value\" in descriptor ? descriptor.value : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction errorKind(error: unknown): string {\n const name = own(error, \"name\");\n if (typeof name === \"string\" && ERROR_NAMES.has(name)) return name;\n try {\n const prototype = Object.getPrototypeOf(error);\n if (prototype === TypeError.prototype) return \"TypeError\";\n if (prototype === RangeError.prototype) return \"RangeError\";\n if (prototype === AggregateError.prototype) return \"AggregateError\";\n } catch {\n /* Untrusted proxies do not contribute type information. */\n }\n return \"Error\";\n}\n\n/** No arbitrary property reads, Error.toJSON, messages, SQL, parameters or function names. */\nexport function failureDiagnostic(input: FailureDiagnosticInput, revision?: string) {\n const causes: Array<{\n kind: string;\n frames: Array<{ locationHash: string; source?: string; line: number; column: number }>;\n }> = [];\n const pgContext: Array<{ functionName: string; line: number }> = [];\n const seen = new Set<unknown>();\n let error = input.error;\n while (error && typeof error === \"object\" && !seen.has(error) && causes.length < 4) {\n seen.add(error);\n pgContext.push(...postgresContext(error).slice(0, 8 - pgContext.length));\n const stack = own(error, \"stack\");\n const frames =\n typeof stack === \"string\"\n ? stack\n .slice(0, 16_384)\n .split(\"\\n\")\n .slice(1, 33)\n .flatMap((frame) => {\n const match = /(?:\\(|\\s)([^\\s()]+):(\\d{1,7}):(\\d{1,7})\\)?$/.exec(frame);\n if (!match) return [];\n // Even a path/function can contain a credential. Keep source-location\n // fingerprints plus line/column, not untrusted textual stack bytes.\n return [\n {\n locationHash: createHash(\"sha256\").update(match[1]!).digest(\"hex\"),\n ...(reviewedSource(match[1]!) ? { source: reviewedSource(match[1]!)! } : {}),\n line: Number(match[2]),\n column: Number(match[3]),\n },\n ];\n })\n : [];\n causes.push({\n kind: errorKind(error),\n frames,\n });\n error = own(error, \"cause\");\n }\n const uuid = (value: unknown) =>\n typeof value === \"string\" &&\n /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value)\n ? value\n : undefined;\n return {\n schema: \"opengeni.failure-diagnostic.v1\",\n diagnosticId: randomUUID(),\n code: CODES.includes(input.code) ? input.code : \"db_failure\",\n stage: STAGES.includes(input.stage) ? input.stage : \"failure_settlement\",\n retryDecision:\n input.retryDecision && RETRIES.includes(input.retryDecision)\n ? input.retryDecision\n : \"unknown\",\n attemptId: uuid(input.attemptId),\n sessionId: uuid(input.sessionId),\n processId: uuid(input.processId),\n turnId: uuid(input.turnId),\n attempts:\n Number.isSafeInteger(input.attempts) && input.attempts! >= 0 && input.attempts! <= 1_000_000\n ? input.attempts\n : undefined,\n sqlState:\n typeof input.sqlState === \"string\" && /^[0-9A-Z]{5}$/.test(input.sqlState)\n ? input.sqlState\n : undefined,\n constraint:\n input.constraint && CONSTRAINTS.has(input.constraint) ? input.constraint : undefined,\n deploymentRevision: revision && /^[0-9a-f]{40}$/.test(revision) ? revision : undefined,\n causes,\n postgresContext: pgContext,\n eventTypes: (input.eventTypes ?? [])\n .slice(0, 32)\n .filter((type) => SessionEventType.safeParse(type).success),\n };\n}\n","/**\n * Per-key warning throttle for repetitive, content-free operational warnings.\n *\n * The first occurrence of a key is always admitted, and so is the first\n * occurrence after a quiet interval. Occurrences inside the interval are only\n * counted, and the key's next admitted line reports how many were suppressed.\n * Keys are process-local and never logged, so a caller may key on a private\n * digest. The key set is bounded: when full, the least recently admitted key is\n * forgotten (its pending suppressed count is lost and it is admitted again as a\n * first occurrence). Metrics stay the exact rate signal; this only bounds logs.\n */\nexport type LogThrottle = {\n /** `null` means \"counted, do not log\"; otherwise log now and report\n * `suppressedCount` occurrences hidden since this key's previous line. */\n admit(key: string): { suppressedCount: number } | null;\n};\n\nexport function createLogThrottle(options: {\n intervalMs: number;\n maxKeys?: number;\n now?: () => number;\n}): LogThrottle {\n const intervalMs = Math.max(0, options.intervalMs);\n const maxKeys = Math.max(1, Math.floor(options.maxKeys ?? 1_024));\n const now = options.now ?? Date.now;\n const entries = new Map<string, { admittedAt: number; suppressed: number }>();\n return {\n admit(key) {\n const at = now();\n const entry = entries.get(key);\n if (entry && at >= entry.admittedAt && at - entry.admittedAt < intervalMs) {\n entry.suppressed += 1;\n return null;\n }\n const suppressedCount = entry?.suppressed ?? 0;\n // Re-insert so Map order tracks the least recently admitted key.\n entries.delete(key);\n if (entries.size >= maxKeys) {\n const oldest = entries.keys().next();\n if (!oldest.done) entries.delete(oldest.value);\n }\n entries.set(key, { admittedAt: at, suppressed: 0 });\n return { suppressedCount };\n },\n };\n}\n"],"mappings":"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","names":["createHash","createHash","createHash"]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-key warning throttle for repetitive, content-free operational warnings.
|
|
3
|
+
*
|
|
4
|
+
* The first occurrence of a key is always admitted, and so is the first
|
|
5
|
+
* occurrence after a quiet interval. Occurrences inside the interval are only
|
|
6
|
+
* counted, and the key's next admitted line reports how many were suppressed.
|
|
7
|
+
* Keys are process-local and never logged, so a caller may key on a private
|
|
8
|
+
* digest. The key set is bounded: when full, the least recently admitted key is
|
|
9
|
+
* forgotten (its pending suppressed count is lost and it is admitted again as a
|
|
10
|
+
* first occurrence). Metrics stay the exact rate signal; this only bounds logs.
|
|
11
|
+
*/
|
|
12
|
+
export type LogThrottle = {
|
|
13
|
+
/** `null` means "counted, do not log"; otherwise log now and report
|
|
14
|
+
* `suppressedCount` occurrences hidden since this key's previous line. */
|
|
15
|
+
admit(key: string): {
|
|
16
|
+
suppressedCount: number;
|
|
17
|
+
} | null;
|
|
18
|
+
};
|
|
19
|
+
export declare function createLogThrottle(options: {
|
|
20
|
+
intervalMs: number;
|
|
21
|
+
maxKeys?: number;
|
|
22
|
+
now?: () => number;
|
|
23
|
+
}): LogThrottle;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opengeni/observability",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.33-canary.36239117573001",
|
|
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": "^5.
|
|
34
|
+
"@opengeni/contracts": "^5.2.0-canary.36239117573001",
|
|
35
35
|
"prom-client": "^15.1.3"
|
|
36
36
|
}
|
|
37
37
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { collectDefaultMetrics, Counter, Gauge, Histogram, Registry } from "prom-client";
|
|
3
3
|
import { SandboxBackend } from "@opengeni/contracts";
|
|
4
|
+
import {
|
|
5
|
+
CLIENT_ERROR_REVISION_PATTERN,
|
|
6
|
+
CLIENT_ERROR_ROUTE_PATTERN,
|
|
7
|
+
} from "@opengeni/contracts/client-error-report";
|
|
4
8
|
import {
|
|
5
9
|
currentTraceContext,
|
|
6
10
|
validTraceContext,
|
|
@@ -10,6 +14,7 @@ import {
|
|
|
10
14
|
import { ExportQueue } from "./export-queue";
|
|
11
15
|
import { failureDiagnostic, type FailureDiagnosticInput } from "./failure-diagnostic";
|
|
12
16
|
export type { FailureDiagnosticInput } from "./failure-diagnostic";
|
|
17
|
+
export { createLogThrottle, type LogThrottle } from "./log-throttle";
|
|
13
18
|
export {
|
|
14
19
|
currentTraceContext,
|
|
15
20
|
withTraceContext,
|
|
@@ -320,6 +325,7 @@ const PUBLIC_TELEMETRY_ATTRIBUTE_KEYS = new Set([
|
|
|
320
325
|
"estimatedDeliveredTokens",
|
|
321
326
|
"fullEvidenceAvailable",
|
|
322
327
|
"retainedOutputKind",
|
|
328
|
+
"suppressedCount",
|
|
323
329
|
]);
|
|
324
330
|
|
|
325
331
|
/** Opaque correlation fields require both a reviewed name and a closed value
|
|
@@ -328,6 +334,11 @@ const PUBLIC_TELEMETRY_ATTRIBUTE_KEYS = new Set([
|
|
|
328
334
|
const PUBLIC_TELEMETRY_OPAQUE_ATTRIBUTE_PATTERNS = new Map<string, RegExp>([
|
|
329
335
|
["sandboxLeaseKey", /^slk_[0-9a-f]{32}$/],
|
|
330
336
|
["correlationId", /^[A-Za-z0-9._:-]{1,128}$/],
|
|
337
|
+
// Web error beacon: a route PATTERN of lowercase literal and `$param`
|
|
338
|
+
// segments (never a concrete path or id) and the bundle revision token, in
|
|
339
|
+
// the exact wire grammar the API route admits.
|
|
340
|
+
["clientRoute", CLIENT_ERROR_ROUTE_PATTERN],
|
|
341
|
+
["clientRevision", CLIENT_ERROR_REVISION_PATTERN],
|
|
331
342
|
]);
|
|
332
343
|
|
|
333
344
|
const PUBLIC_CHANNEL_A_OPERATIONS = new Set([
|
|
@@ -394,6 +405,7 @@ const PUBLIC_TELEMETRY_ERROR_CLASSES = new Set([
|
|
|
394
405
|
"GitCredentialRenewalOperationError",
|
|
395
406
|
"HostExportOperationError",
|
|
396
407
|
"HttpOperationError",
|
|
408
|
+
"KnowledgeIndexOperationError",
|
|
397
409
|
"McpLifecycleError",
|
|
398
410
|
"McpOperationError",
|
|
399
411
|
"MemoryEmbeddingOperationError",
|
|
@@ -443,6 +455,11 @@ const PUBLIC_TELEMETRY_ERROR_CODES = new Set([
|
|
|
443
455
|
"idempotency_conflict",
|
|
444
456
|
"incompatible_exposed_ports",
|
|
445
457
|
"internal_error",
|
|
458
|
+
"knowledge_index_defer_failed",
|
|
459
|
+
"knowledge_index_embedding_failed",
|
|
460
|
+
"knowledge_index_failed",
|
|
461
|
+
"knowledge_index_persistence_failed",
|
|
462
|
+
"knowledge_index_usage_limit_reached",
|
|
446
463
|
"limit_exceeded",
|
|
447
464
|
"mcp_close_failed",
|
|
448
465
|
"mcp_connect_failed",
|
|
@@ -1508,6 +1525,7 @@ function projectPublicTelemetryAttributes(attributes: Attributes): Attributes {
|
|
|
1508
1525
|
...projectPublicChannelADiagnosticAttributes(attributes),
|
|
1509
1526
|
...projectApiFatalDiagnosticAttributes(attributes),
|
|
1510
1527
|
...projectSnapshotDiagnosticAttributes(attributes),
|
|
1528
|
+
...projectKnowledgeIndexDiagnosticAttributes(attributes),
|
|
1511
1529
|
...projectPublicDiagnosticAttributes(attributes),
|
|
1512
1530
|
};
|
|
1513
1531
|
}
|
|
@@ -1630,6 +1648,13 @@ function projectSnapshotDiagnosticAttributes(attributes: Attributes): Attributes
|
|
|
1630
1648
|
return projected;
|
|
1631
1649
|
}
|
|
1632
1650
|
|
|
1651
|
+
function projectKnowledgeIndexDiagnosticAttributes(attributes: Attributes): Attributes {
|
|
1652
|
+
if (attributes.errorClass !== "KnowledgeIndexOperationError") return {};
|
|
1653
|
+
const sqlState = attributes.sqlState;
|
|
1654
|
+
// A SQLSTATE is a five-character protocol code, never message or SQL text.
|
|
1655
|
+
return typeof sqlState === "string" && /^[0-9A-Z]{5}$/.test(sqlState) ? { sqlState } : {};
|
|
1656
|
+
}
|
|
1657
|
+
|
|
1633
1658
|
function projectPublicDiagnosticAttributes(attributes: Attributes): Attributes {
|
|
1634
1659
|
const errorClass = attributes.errorClass;
|
|
1635
1660
|
const errorCode = attributes.errorCode;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-key warning throttle for repetitive, content-free operational warnings.
|
|
3
|
+
*
|
|
4
|
+
* The first occurrence of a key is always admitted, and so is the first
|
|
5
|
+
* occurrence after a quiet interval. Occurrences inside the interval are only
|
|
6
|
+
* counted, and the key's next admitted line reports how many were suppressed.
|
|
7
|
+
* Keys are process-local and never logged, so a caller may key on a private
|
|
8
|
+
* digest. The key set is bounded: when full, the least recently admitted key is
|
|
9
|
+
* forgotten (its pending suppressed count is lost and it is admitted again as a
|
|
10
|
+
* first occurrence). Metrics stay the exact rate signal; this only bounds logs.
|
|
11
|
+
*/
|
|
12
|
+
export type LogThrottle = {
|
|
13
|
+
/** `null` means "counted, do not log"; otherwise log now and report
|
|
14
|
+
* `suppressedCount` occurrences hidden since this key's previous line. */
|
|
15
|
+
admit(key: string): { suppressedCount: number } | null;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export function createLogThrottle(options: {
|
|
19
|
+
intervalMs: number;
|
|
20
|
+
maxKeys?: number;
|
|
21
|
+
now?: () => number;
|
|
22
|
+
}): LogThrottle {
|
|
23
|
+
const intervalMs = Math.max(0, options.intervalMs);
|
|
24
|
+
const maxKeys = Math.max(1, Math.floor(options.maxKeys ?? 1_024));
|
|
25
|
+
const now = options.now ?? Date.now;
|
|
26
|
+
const entries = new Map<string, { admittedAt: number; suppressed: number }>();
|
|
27
|
+
return {
|
|
28
|
+
admit(key) {
|
|
29
|
+
const at = now();
|
|
30
|
+
const entry = entries.get(key);
|
|
31
|
+
if (entry && at >= entry.admittedAt && at - entry.admittedAt < intervalMs) {
|
|
32
|
+
entry.suppressed += 1;
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
const suppressedCount = entry?.suppressed ?? 0;
|
|
36
|
+
// Re-insert so Map order tracks the least recently admitted key.
|
|
37
|
+
entries.delete(key);
|
|
38
|
+
if (entries.size >= maxKeys) {
|
|
39
|
+
const oldest = entries.keys().next();
|
|
40
|
+
if (!oldest.done) entries.delete(oldest.value);
|
|
41
|
+
}
|
|
42
|
+
entries.set(key, { admittedAt: at, suppressed: 0 });
|
|
43
|
+
return { suppressedCount };
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
}
|