@vreko/cli 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +45 -0
  3. package/dist/CeremonyView-LQS7FTMK.js +134 -0
  4. package/dist/CeremonyView-LQS7FTMK.js.map +1 -0
  5. package/dist/InitApp-7K5DTYSW.js +1479 -0
  6. package/dist/InitApp-7K5DTYSW.js.map +1 -0
  7. package/dist/SkippedTestDetector-PJSKSOZR.js +7 -0
  8. package/dist/SkippedTestDetector-PJSKSOZR.js.map +1 -0
  9. package/dist/TuiApp-FX23XQBK.js +8 -0
  10. package/dist/TuiApp-FX23XQBK.js.map +1 -0
  11. package/dist/analysis-ABEO6RTN.js +8 -0
  12. package/dist/analysis-ABEO6RTN.js.map +1 -0
  13. package/dist/auth-XNBEBNPY.js +7669 -0
  14. package/dist/auth-XNBEBNPY.js.map +1 -0
  15. package/dist/ceremony-M7CXVBVA.js +45 -0
  16. package/dist/ceremony-M7CXVBVA.js.map +1 -0
  17. package/dist/chunk-A3QSZJPD.js +3147 -0
  18. package/dist/chunk-A3QSZJPD.js.map +1 -0
  19. package/dist/chunk-ASGZ5B6C.js +3969 -0
  20. package/dist/chunk-ASGZ5B6C.js.map +1 -0
  21. package/dist/chunk-DMXC2JTC.js +58 -0
  22. package/dist/chunk-DMXC2JTC.js.map +1 -0
  23. package/dist/chunk-EEBSK2IH.js +161 -0
  24. package/dist/chunk-EEBSK2IH.js.map +1 -0
  25. package/dist/chunk-EWOJGXRX.js +22 -0
  26. package/dist/chunk-EWOJGXRX.js.map +1 -0
  27. package/dist/chunk-F7GEJLP7.js +2389 -0
  28. package/dist/chunk-F7GEJLP7.js.map +1 -0
  29. package/dist/chunk-GOYL3F4T.js +605 -0
  30. package/dist/chunk-GOYL3F4T.js.map +1 -0
  31. package/dist/chunk-GRMRYWYS.js +17 -0
  32. package/dist/chunk-GRMRYWYS.js.map +1 -0
  33. package/dist/chunk-GSUGROXB.js +1951 -0
  34. package/dist/chunk-GSUGROXB.js.map +1 -0
  35. package/dist/chunk-H7773ONB.js +50 -0
  36. package/dist/chunk-H7773ONB.js.map +1 -0
  37. package/dist/chunk-HFQHU5LC.js +445 -0
  38. package/dist/chunk-HFQHU5LC.js.map +1 -0
  39. package/dist/chunk-IVHUBLJD.js +318 -0
  40. package/dist/chunk-IVHUBLJD.js.map +1 -0
  41. package/dist/chunk-KJWKY4L4.js +14 -0
  42. package/dist/chunk-KJWKY4L4.js.map +1 -0
  43. package/dist/chunk-MJVY2XUN.js +1793 -0
  44. package/dist/chunk-MJVY2XUN.js.map +1 -0
  45. package/dist/chunk-QWZVCJII.js +1797 -0
  46. package/dist/chunk-QWZVCJII.js.map +1 -0
  47. package/dist/chunk-VTSNRV3V.js +3237 -0
  48. package/dist/chunk-VTSNRV3V.js.map +1 -0
  49. package/dist/chunk-W5B4GTXR.js +1466 -0
  50. package/dist/chunk-W5B4GTXR.js.map +1 -0
  51. package/dist/chunk-WZEZLVOW.js +4995 -0
  52. package/dist/chunk-WZEZLVOW.js.map +1 -0
  53. package/dist/chunk-YPTTIXKC.js +199 -0
  54. package/dist/chunk-YPTTIXKC.js.map +1 -0
  55. package/dist/chunk-Z55UGM6X.js +6360 -0
  56. package/dist/chunk-Z55UGM6X.js.map +1 -0
  57. package/dist/chunk-ZIIRQODJ.js +110 -0
  58. package/dist/chunk-ZIIRQODJ.js.map +1 -0
  59. package/dist/chunk-ZSUQ4FMB.js +77 -0
  60. package/dist/chunk-ZSUQ4FMB.js.map +1 -0
  61. package/dist/client-JMTSZS3V.js +10 -0
  62. package/dist/client-JMTSZS3V.js.map +1 -0
  63. package/dist/deprecated-snap.js +19 -0
  64. package/dist/deprecated-snap.js.map +1 -0
  65. package/dist/dist-2KWBZFLA.js +14 -0
  66. package/dist/dist-2KWBZFLA.js.map +1 -0
  67. package/dist/dist-5ZYKNNU3.js +7 -0
  68. package/dist/dist-5ZYKNNU3.js.map +1 -0
  69. package/dist/dist-CP3RFHPI.js +11 -0
  70. package/dist/dist-CP3RFHPI.js.map +1 -0
  71. package/dist/gecko-53ITAGG6.js +56 -0
  72. package/dist/gecko-53ITAGG6.js.map +1 -0
  73. package/dist/guards-QAFC64NO.js +7 -0
  74. package/dist/guards-QAFC64NO.js.map +1 -0
  75. package/dist/index.js +57785 -0
  76. package/dist/index.js.map +1 -0
  77. package/dist/init-command-246JIVXM.js +7 -0
  78. package/dist/init-command-246JIVXM.js.map +1 -0
  79. package/dist/init-core-KAI7LCXZ.js +12 -0
  80. package/dist/init-core-KAI7LCXZ.js.map +1 -0
  81. package/dist/init-scan-RZNYDTUV.js +1919 -0
  82. package/dist/init-scan-RZNYDTUV.js.map +1 -0
  83. package/dist/local-service-adapter-6KNN6WQL.js +8 -0
  84. package/dist/local-service-adapter-6KNN6WQL.js.map +1 -0
  85. package/dist/secure-credentials-JXWAQLS2.js +306 -0
  86. package/dist/secure-credentials-JXWAQLS2.js.map +1 -0
  87. package/dist/tui-TPJPUS2R.js +111 -0
  88. package/dist/tui-TPJPUS2R.js.map +1 -0
  89. package/dist/vreko-dir-O3RLG7PI.js +8 -0
  90. package/dist/vreko-dir-O3RLG7PI.js.map +1 -0
  91. package/package.json +132 -0
  92. package/scripts/check-banned-words.ts +152 -0
  93. package/scripts/hooks/posttooluse-file-notify.sh +108 -0
  94. package/scripts/hooks/pretooluse-fragile-guard.sh +82 -0
  95. package/scripts/post-install-notice.js +24 -0
  96. package/scripts/postinstall.mjs +84 -0
  97. package/scripts/preuninstall.mjs +34 -0
  98. package/scripts/verify-jsx-transform.mjs +55 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../packages/infrastructure/package.json","../../../packages/infrastructure/src/environment/index.ts","../../../packages/infrastructure/src/graceful-shutdown/index.ts","../../../packages/infrastructure/src/health/index.ts","../../../packages/infrastructure/src/metrics/core/events.ts","../../../packages/infrastructure/src/neon/index.ts","../../../packages/infrastructure/src/neon/client.ts","../../../packages/infrastructure/src/neon/migrations.ts","../../../packages/infrastructure/src/observability/vocabulary.ts","../../../packages/infrastructure/src/observability/wrapper.ts","../../../packages/infrastructure/src/observability/agent-session.ts","../../../packages/infrastructure/src/observability/retro-queries.ts","../../../packages/infrastructure/src/posthog/alerts.ts","../../../packages/infrastructure/src/posthog/cohorts.ts","../../../packages/infrastructure/src/posthog/correlation.ts","../../../packages/infrastructure/src/prometheus/index.ts","../../../packages/infrastructure/src/sentry/index.ts","../../../packages/infrastructure/src/tracing/error-budget.ts","../../../packages/infrastructure/src/tracing/otel-provider.ts","../../../packages/infrastructure/src/tracing/telemetry-client.ts"],"names":["logger","__filename","__dirname","neon","AgentAction","LLMProvider","AgentRole","randomUUID","NETWORK_TIMEOUT_MS","trace","PostHog","posthogClient","getPostHog","posthogHost","ProfilingIntegration","context","getMetrics","OTelSpanAdapter","OTelSpanStatusCode"],"mappings":"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","file":"chunk-A3QSZJPD.js","sourcesContent":["{\n \"name\": \"@vreko/infrastructure\",\n \"version\": \"0.2.0\",\n \"license\": \"Apache-2.0\",\n \"author\": \"Vreko Team\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/vreko-dev.git\",\n \"directory\": \"packages/infrastructure\"\n },\n \"files\": [\n \"dist\"\n ],\n \"dependencies\": {\n \"@neondatabase/serverless\": \"catalog:\",\n \"@opentelemetry/api\": \"catalog:\",\n \"@opentelemetry/exporter-metrics-otlp-http\": \"catalog:\",\n \"@opentelemetry/exporter-trace-otlp-http\": \"catalog:\",\n \"@opentelemetry/instrumentation-pg\": \"catalog:\",\n \"@opentelemetry/instrumentation-pino\": \"catalog:\",\n \"@opentelemetry/resources\": \"catalog:\",\n \"@opentelemetry/sdk-metrics\": \"catalog:\",\n \"@opentelemetry/sdk-trace-base\": \"catalog:\",\n \"@opentelemetry/sdk-trace-node\": \"catalog:\",\n \"@opentelemetry/semantic-conventions\": \"catalog:\",\n \"@vreko/contracts\": \"workspace:*\",\n \"bullmq\": \"catalog:\",\n \"nanoid\": \"catalog:\",\n \"pino\": \"catalog:\",\n \"posthog-node\": \"catalog:\",\n \"opossum\": \"catalog:\",\n \"p-queue\": \"catalog:\",\n \"p-retry\": \"catalog:\",\n \"lru-cache\": \"catalog:\",\n \"chokidar\": \"catalog:\",\n \"prom-client\": \"catalog:\"\n },\n \"optionalDependencies\": {\n \"@sentry/node\": \"catalog:\",\n \"@sentry/profiling-node\": \"catalog:\"\n },\n \"devDependencies\": {\n \"@vreko/tsconfig\": \"workspace:*\",\n \"@types/node\": \"catalog:\",\n \"posthog-js\": \"catalog:\",\n \"tsup\": \"catalog:\",\n \"typescript\": \"catalog:\",\n \"vitest\": \"catalog:\"\n },\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"default\": \"./dist/index.js\"\n },\n \"./logging/logger\": {\n \"types\": \"./dist/logging/logger.d.ts\",\n \"default\": \"./dist/logging/logger.js\"\n },\n \"./observability\": {\n \"types\": \"./dist/observability/index.d.ts\",\n \"default\": \"./dist/observability/index.js\"\n },\n \"./observability/index\": {\n \"types\": \"./dist/observability/index.d.ts\",\n \"default\": \"./dist/observability/index.js\"\n },\n \"./observability/vocabulary\": {\n \"types\": \"./dist/observability/vocabulary.d.ts\",\n \"default\": \"./dist/observability/vocabulary.js\"\n },\n \"./observability/wrapper\": {\n \"types\": \"./dist/observability/wrapper.d.ts\",\n \"default\": \"./dist/observability/wrapper.js\"\n },\n \"./observability/retro-queries\": {\n \"types\": \"./dist/observability/retro-queries.d.ts\",\n \"default\": \"./dist/observability/retro-queries.js\"\n },\n \"./metrics\": {\n \"types\": \"./dist/metrics/index.d.ts\",\n \"default\": \"./dist/metrics/index.js\"\n },\n \"./tracing\": {\n \"types\": \"./dist/tracing/index.d.ts\",\n \"default\": \"./dist/tracing/index.js\"\n },\n \"./health\": {\n \"types\": \"./dist/health/index.d.ts\",\n \"default\": \"./dist/health/index.js\"\n },\n \"./resiliency\": {\n \"types\": \"./dist/resiliency/index.d.ts\",\n \"default\": \"./dist/resiliency/index.js\"\n },\n \"./cache\": {\n \"types\": \"./dist/cache/index.d.ts\",\n \"default\": \"./dist/cache/index.js\"\n },\n \"./files\": {\n \"types\": \"./dist/files/watcher.d.ts\",\n \"default\": \"./dist/files/watcher.js\"\n },\n \"./sqlite\": {\n \"types\": \"./dist/sqlite/index.d.ts\",\n \"default\": \"./dist/sqlite/index.js\"\n },\n \"./neon\": {\n \"types\": \"./dist/neon/index.d.ts\",\n \"default\": \"./dist/neon/index.js\"\n },\n \"./prometheus\": {\n \"types\": \"./dist/prometheus/index.d.ts\",\n \"default\": \"./dist/prometheus/index.js\"\n },\n \"./queue/email-queue-service\": {\n \"types\": \"./dist/queue/email-queue-service.d.ts\",\n \"default\": \"./dist/queue/email-queue-service.js\"\n },\n \"./queue/flywheel-queue-service\": {\n \"types\": \"./dist/queue/flywheel-queue-service.d.ts\",\n \"default\": \"./dist/queue/flywheel-queue-service.js\"\n },\n \"./sentry\": {\n \"types\": \"./dist/sentry/index.d.ts\",\n \"default\": \"./dist/sentry/index.js\"\n }\n },\n \"publishConfig\": {\n \"exports\": {\n \".\": {\n \"types\": \"./dist/logging/logger.d.ts\",\n \"default\": \"./dist/logging/logger.js\"\n },\n \"./logging/logger\": {\n \"types\": \"./dist/logging/logger.d.ts\",\n \"default\": \"./dist/logging/logger.js\"\n },\n \"./observability\": {\n \"types\": \"./dist/observability/index.d.ts\",\n \"default\": \"./dist/observability/index.js\"\n },\n \"./observability/index\": {\n \"types\": \"./dist/observability/index.d.ts\",\n \"default\": \"./dist/observability/index.js\"\n },\n \"./observability/vocabulary\": {\n \"types\": \"./dist/observability/vocabulary.d.ts\",\n \"default\": \"./dist/observability/vocabulary.js\"\n },\n \"./observability/wrapper\": {\n \"types\": \"./dist/observability/wrapper.d.ts\",\n \"default\": \"./dist/observability/wrapper.js\"\n },\n \"./observability/retro-queries\": {\n \"types\": \"./dist/observability/retro-queries.d.ts\",\n \"default\": \"./dist/observability/retro-queries.js\"\n },\n \"./health\": {\n \"types\": \"./dist/health/index.d.ts\",\n \"default\": \"./dist/health/index.js\"\n },\n \"./tracing\": {\n \"types\": \"./dist/tracing/index.d.ts\",\n \"default\": \"./dist/tracing/index.js\"\n },\n \"./metrics\": {\n \"types\": \"./dist/metrics/index.d.ts\",\n \"default\": \"./dist/metrics/index.js\"\n },\n \"./resiliency\": {\n \"types\": \"./dist/resiliency/index.d.ts\",\n \"default\": \"./dist/resiliency/index.js\"\n },\n \"./cache\": {\n \"types\": \"./dist/cache/index.d.ts\",\n \"default\": \"./dist/cache/index.js\"\n },\n \"./files\": {\n \"types\": \"./dist/files/watcher.d.ts\",\n \"default\": \"./dist/files/watcher.js\"\n },\n \"./sqlite\": {\n \"types\": \"./dist/sqlite/index.d.ts\",\n \"default\": \"./dist/sqlite/index.js\"\n },\n \"./neon\": {\n \"types\": \"./dist/neon/index.d.ts\",\n \"default\": \"./dist/neon/index.js\"\n },\n \"./queue/email-queue-service\": {\n \"types\": \"./dist/queue/email-queue-service.d.ts\",\n \"default\": \"./dist/queue/email-queue-service.js\"\n },\n \"./queue/flywheel-queue-service\": {\n \"types\": \"./dist/queue/flywheel-queue-service.d.ts\",\n \"default\": \"./dist/queue/flywheel-queue-service.js\"\n },\n \"./sentry\": {\n \"types\": \"./dist/sentry/index.d.ts\",\n \"default\": \"./dist/sentry/index.js\"\n }\n }\n },\n \"main\": \"dist/index.js\",\n \"private\": true,\n \"scripts\": {\n \"build\": \"tsup --no-dts && tsc --build tsconfig.build.json --force && node ../../scripts/build-utils/add-js-extensions.mjs\",\n \"build:docker\": \"tsup --no-dts && node ../../scripts/build-utils/add-js-extensions.mjs\",\n \"dev\": \"tsup --watch\",\n \"check\": \"biome check .\",\n \"format\": \"biome format --write .\",\n \"lint\": \"biome lint .\",\n \"lint:fix\": \"biome lint --fix .\",\n \"postbuild\": \"test -f dist/index.d.ts && node scripts/patch-dts.cjs || echo 'Warning: Type declarations not fully generated'\",\n \"test\": \"vitest run\",\n \"test:coverage\": \"vitest run --coverage\",\n \"test:watch\": \"vitest\",\n \"type-check\": \"tsc --noEmit\"\n },\n \"type\": \"module\",\n \"types\": \"dist/index.d.ts\"\n}\n","/**\n * Environment Detection Utilities\n *\n * Provides consistent environment detection across all surfaces (web, api, cli, vscode, mcp).\n *\n * CRITICAL: NODE_ENV is unreliable because Doppler sets it to \"production\" even locally.\n * Use DEPLOYMENT_ENV or hostname-based detection instead.\n *\n * @example\n * ```typescript\n * import { getDeploymentEnv, isDevelopment, getAnalyticsEnv } from '@vreko/infrastructure/environment';\n *\n * // Get the deployment environment\n * const env = getDeploymentEnv(); // 'development' | 'production'\n *\n * // Check if running in development\n * if (isDevelopment()) {\n * logger.debug(...);\n * }\n *\n * // Get environment for analytics\n * const analyticsEnv = getAnalyticsEnv(); // { env: 'dev' | 'prod', surface: string }\n * ```\n */\n\nexport type DeploymentEnvironment = \"development\" | \"staging\" | \"production\";\n\nexport type AnalyticsEnvironment = \"dev\" | \"prod\";\n\nexport type Surface = \"web\" | \"api\" | \"cli\" | \"vscode\" | \"mcp\" | \"daemon\";\n\n/**\n * Detect if running in local development environment\n *\n * Detection priority:\n * 1. DEPLOYMENT_ENV environment variable (explicit override)\n * 2. VERCEL_ENV or FLY_ALLOC_ID (cloud deployment = production)\n * 3. BETTER_AUTH_URL contains localhost (local dev server)\n * 4. Hostname is localhost/127.0.0.1/*.local (client-side)\n */\nexport function isDevelopment(): boolean {\n\treturn getDeploymentEnv() === \"development\";\n}\n\n/**\n * Detect if running in production environment\n */\nexport function isProduction(): boolean {\n\treturn getDeploymentEnv() === \"production\";\n}\n\n/**\n * Get the deployment environment\n *\n * Priority:\n * 1. DEPLOYMENT_ENV env var (explicit)\n * 2. CI + VERCEL/FLY = production\n * 3. localhost detection = development\n * 4. Default = production (safe default)\n */\nexport function getDeploymentEnv(): DeploymentEnvironment {\n\t// 1. Explicit override\n\tconst explicitEnv = process.env.DEPLOYMENT_ENV;\n\tif (explicitEnv === \"development\" || explicitEnv === \"staging\" || explicitEnv === \"production\") {\n\t\treturn explicitEnv;\n\t}\n\n\t// 2. Cloud deployment detection\n\tif (process.env.VERCEL || process.env.VERCEL_ENV || process.env.FLY_ALLOC_ID) {\n\t\treturn \"production\";\n\t}\n\n\t// 3. Local development detection (server-side)\n\tconst authUrl = process.env.BETTER_AUTH_URL || process.env.APP_URL || \"\";\n\tif (authUrl.includes(\"localhost\") || authUrl.includes(\"127.0.0.1\")) {\n\t\treturn \"development\";\n\t}\n\n\t// 4. Client-side detection (browser)\n\tif (typeof window !== \"undefined\") {\n\t\tconst hostname = window.location.hostname;\n\t\tif (\n\t\t\thostname === \"localhost\" ||\n\t\t\thostname === \"127.0.0.1\" ||\n\t\t\thostname.endsWith(\".local\") ||\n\t\t\thostname.endsWith(\".test\")\n\t\t) {\n\t\t\treturn \"development\";\n\t\t}\n\t}\n\n\t// 5. CI detection (GitHub Actions, etc.)\n\tif (process.env.CI) {\n\t\t// CI without cloud deployment flags = likely testing/staging\n\t\treturn \"production\";\n\t}\n\n\t// 6. Safe default\n\treturn \"production\";\n}\n\n/**\n * Get analytics environment string (shorter format for PostHog)\n */\nexport function getAnalyticsEnv(): AnalyticsEnvironment {\n\treturn getDeploymentEnv() === \"development\" ? \"dev\" : \"prod\";\n}\n\n/**\n * Get environment info for logging/debugging\n */\nexport function getEnvironmentInfo(): {\n\tdeployment: DeploymentEnvironment;\n\tanalytics: AnalyticsEnvironment;\n\tnodeEnv: string | undefined;\n\tisCi: boolean;\n\tisVercel: boolean;\n\tisFly: boolean;\n\tisLocalhost: boolean;\n} {\n\tconst deployment = getDeploymentEnv();\n\treturn {\n\t\tdeployment,\n\t\tanalytics: deployment === \"development\" ? \"dev\" : \"prod\",\n\t\tnodeEnv: process.env.NODE_ENV,\n\t\tisCi: !!process.env.CI,\n\t\tisVercel: !!(process.env.VERCEL || process.env.VERCEL_ENV),\n\t\tisFly: !!process.env.FLY_ALLOC_ID,\n\t\tisLocalhost:\n\t\t\t(process.env.BETTER_AUTH_URL?.includes(\"localhost\") ?? false) ||\n\t\t\t(typeof window !== \"undefined\" &&\n\t\t\t\t(window.location.hostname === \"localhost\" || window.location.hostname === \"127.0.0.1\")),\n\t};\n}\n\n/**\n * Detect current surface based on environment\n */\nexport function detectSurface(): Surface {\n\t// VS Code extension\n\tif (process.env.VSCODE_EXTENSION || typeof process.env.VSCODE_PID !== \"undefined\") {\n\t\treturn \"vscode\";\n\t}\n\n\t// CLI\n\tif (process.env.VREKO_CLI || process.argv[1]?.includes(\"cli\")) {\n\t\treturn \"cli\";\n\t}\n\n\t// MCP server\n\tif (process.env.MCP_SERVER || process.env.MCP_MODE) {\n\t\treturn \"mcp\";\n\t}\n\n\t// Daemon (local service)\n\tif (process.env.DAEMON_MODE || process.env.LOCAL_SERVICE) {\n\t\treturn \"daemon\";\n\t}\n\n\t// API server\n\tif (process.env.API_SERVER || typeof process.env.PORT !== \"undefined\") {\n\t\treturn \"api\";\n\t}\n\n\t// Web (client-side default)\n\tif (typeof window !== \"undefined\") {\n\t\treturn \"web\";\n\t}\n\n\t// Server-side default\n\treturn \"api\";\n}\n\n/**\n * Get super properties for PostHog analytics\n */\nexport function getAnalyticsSuperProperties(surface?: Surface): {\n\tenv: AnalyticsEnvironment;\n\tsurface: Surface;\n} {\n\treturn {\n\t\tenv: getAnalyticsEnv(),\n\t\tsurface: surface ?? detectSurface(),\n\t};\n}\n","/**\n * Graceful Shutdown Handler - 2026 Enterprise Pattern\n *\n * Implements proper graceful shutdown with:\n * - Connection draining\n * - Timeout handling\n * - Cleanup handler registration\n * - Health check integration\n *\n * @see https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-termination\n * @see https://fly.io/docs/blueprints/seamless-deployments/\n */\n\nimport type { Logger } from \"../logging/logger.js\";\n\nexport interface GracefulShutdownOptions {\n\t/** Logger instance */\n\tlogger: Logger;\n\t/** Shutdown timeout in milliseconds (default: 25000ms to fit within 30s kill_timeout) */\n\ttimeoutMs?: number;\n\t/** Health check marker file path (optional) */\n\thealthMarkerPath?: string;\n}\n\nexport interface ShutdownHandler {\n\t/** Register a cleanup handler to be called during shutdown */\n\tregister(handler: () => Promise<void>): void;\n\t/** Mark the service as ready (health checks will pass) */\n\tsetReady(): void;\n\t/** Mark the service as not ready (health checks will fail) */\n\tsetNotReady(): void;\n\t/** Initialize the shutdown handler (attach signal listeners) */\n\tinit(): void;\n\t/** Check if the service is ready */\n\tisReady(): boolean;\n\t/** Check if shutdown is in progress */\n\tisShuttingDown(): boolean;\n}\n\n/**\n * Create a graceful shutdown handler\n *\n * 2026 Pattern: Implements proper graceful shutdown sequence:\n * 1. Set not ready (health checks fail, stop routing traffic)\n * 2. Wait briefly for in-flight requests to complete\n * 3. Run cleanup handlers in reverse order (LIFO)\n * 4. Force exit if timeout is reached\n */\nexport function createGracefulShutdown(options: GracefulShutdownOptions): ShutdownHandler {\n\tconst { logger, timeoutMs = 25000, healthMarkerPath } = options;\n\n\tconst cleanupHandlers: Array<() => Promise<void>> = [];\n\tlet isShuttingDown = false;\n\tlet isReady = false;\n\n\t/**\n\t * Set readiness state (for health checks)\n\t */\n\tfunction updateReadiness(ready: boolean): void {\n\t\tisReady = ready;\n\n\t\t// Optionally write health marker file for external checks\n\t\tif (healthMarkerPath) {\n\t\t\ttry {\n\t\t\t\tif (ready) {\n\t\t\t\t\t// Write marker file to indicate ready\n\t\t\t\t\t// @ts-expect-error - Bun global may not exist\n\t\t\t\t\tglobalThis.Bun?.write?.(healthMarkerPath, process.pid.toString());\n\t\t\t\t} else {\n\t\t\t\t\t// Remove marker file to indicate not ready\n\t\t\t\t\t// @ts-expect-error - Bun global may not exist\n\t\t\t\t\tglobalThis.Bun?.write?.(healthMarkerPath, \"\");\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tlogger.debug(\"Health marker file operation failed\", { error });\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Execute shutdown sequence\n\t */\n\tasync function shutdown(signal: string): Promise<void> {\n\t\tif (isShuttingDown) {\n\t\t\tlogger.warn(\"Shutdown already in progress, ignoring signal\", { signal });\n\t\t\treturn;\n\t\t}\n\n\t\tisShuttingDown = true;\n\t\tlogger.info(\"Shutdown initiated\", { signal, pid: process.pid });\n\n\t\t// Step 1: Mark as not ready immediately\n\t\t// This tells load balancers to stop routing new traffic\n\t\tupdateReadiness(false);\n\t\tlogger.info(\"Service marked as not ready, stopping new traffic\");\n\n\t\t// Step 2: Wait briefly for in-flight requests\n\t\t// This is critical for zero-downtime deployments\n\t\tconst drainTimeout = Math.min(5000, timeoutMs / 5);\n\t\tlogger.info(\"Waiting for in-flight requests to complete\", { drainTimeoutMs: drainTimeout });\n\t\tawait new Promise((resolve) => setTimeout(resolve, drainTimeout));\n\n\t\t// Step 3: Run cleanup handlers in reverse order (LIFO)\n\t\tlogger.info(\"Running cleanup handlers\", { count: cleanupHandlers.length });\n\n\t\tconst cleanupTimeout = timeoutMs - drainTimeout - 2000; // Leave 2s buffer\n\t\tconst cleanupStart = Date.now();\n\n\t\tfor (let i = cleanupHandlers.length - 1; i >= 0; i--) {\n\t\t\tconst remainingTime = cleanupTimeout - (Date.now() - cleanupStart);\n\t\t\tif (remainingTime <= 0) {\n\t\t\t\tlogger.warn(\"Cleanup timeout reached, some handlers may not have completed\");\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst handler = cleanupHandlers[i];\n\t\t\t\tconst handlerTimeout = Math.min(remainingTime, 5000);\n\n\t\t\t\t// Run handler with timeout\n\t\t\t\tawait Promise.race([\n\t\t\t\t\thandler(),\n\t\t\t\t\tnew Promise((_, reject) => setTimeout(() => reject(new Error(\"Handler timeout\")), handlerTimeout)),\n\t\t\t\t]);\n\t\t\t} catch (error) {\n\t\t\t\tlogger.error(\"Cleanup handler error\", { error, handlerIndex: i });\n\t\t\t}\n\t\t}\n\n\t\tlogger.info(\"Shutdown complete\", {\n\t\t\tdurationMs: Date.now() - cleanupStart + drainTimeout,\n\t\t});\n\n\t\tprocess.exit(0);\n\t}\n\n\t// Force exit after timeout\n\tconst forceExit = (): never => {\n\t\tlogger.error(\"Forced exit due to timeout\", { timeoutMs });\n\t\tprocess.exit(1);\n\t};\n\n\treturn {\n\t\tregister(handler: () => Promise<void>): void {\n\t\t\tcleanupHandlers.push(handler);\n\t\t},\n\n\t\tsetReady(): void {\n\t\t\tupdateReadiness(true);\n\t\t},\n\n\t\tsetNotReady(): void {\n\t\t\tupdateReadiness(false);\n\t\t},\n\n\t\tinit(): void {\n\t\t\t// Handle termination signals\n\t\t\tconst handleShutdown = (signal: string) => {\n\t\t\t\tshutdown(signal).catch((error) => {\n\t\t\t\t\tlogger.error(\"Shutdown error\", { error });\n\t\t\t\t\tprocess.exit(1);\n\t\t\t\t});\n\n\t\t\t\t// Set force exit timeout\n\t\t\t\tsetTimeout(forceExit, timeoutMs);\n\t\t\t};\n\n\t\t\tprocess.on(\"SIGTERM\", () => handleShutdown(\"SIGTERM\"));\n\t\t\tprocess.on(\"SIGINT\", () => handleShutdown(\"SIGINT\"));\n\n\t\t\t// Handle uncaught errors\n\t\t\tprocess.on(\"uncaughtException\", (error) => {\n\t\t\t\tlogger.error(\"Uncaught exception, initiating shutdown\", { error });\n\t\t\t\thandleShutdown(\"uncaughtException\");\n\t\t\t});\n\n\t\t\tprocess.on(\"unhandledRejection\", (reason) => {\n\t\t\t\tlogger.error(\"Unhandled rejection, initiating shutdown\", { reason });\n\t\t\t\t// Don't shutdown on unhandled rejection in production\n\t\t\t\t// Just log it - this is often recoverable\n\t\t\t\tif (process.env.NODE_ENV !== \"production\") {\n\t\t\t\t\thandleShutdown(\"unhandledRejection\");\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tlogger.info(\"Graceful shutdown handler initialized\", { timeoutMs });\n\t\t},\n\n\t\tisReady(): boolean {\n\t\t\treturn isReady;\n\t\t},\n\n\t\tisShuttingDown(): boolean {\n\t\t\treturn isShuttingDown;\n\t\t},\n\t};\n}\n\n/**\n * Server shutdown helper with connection draining\n */\nexport async function drainAndCloseServer(\n\tserver: {\n\t\tclose: () => Promise<void> | void;\n\t\tcloseIdleConnections?: () => void;\n\t\tcloseAllConnections?: () => void;\n\t},\n\tlogger: Logger,\n): Promise<void> {\n\tlogger.info(\"Closing server...\");\n\n\t// Step 1: Stop accepting new connections\n\t// server.close() stops accepting new connections but keeps existing ones\n\tconst closePromise = server.close();\n\n\t// Step 2: Close idle connections immediately (Node 18.2.0+)\n\tif (server.closeIdleConnections) {\n\t\tlogger.info(\"Closing idle connections...\");\n\t\tserver.closeIdleConnections();\n\t}\n\n\t// Step 3: Wait for active connections to finish or timeout\n\tconst timeout = 10000; // 10 seconds\n\tawait Promise.race([closePromise, new Promise((resolve) => setTimeout(resolve, timeout))]);\n\n\t// Step 4: Force close remaining connections (Node 18.2.0+)\n\tif (server.closeAllConnections) {\n\t\tlogger.info(\"Force closing remaining connections...\");\n\t\tserver.closeAllConnections();\n\t}\n\n\tlogger.info(\"Server closed\");\n}\n\n/**\n * PreStop hook helper for containers\n * Call this when receiving shutdown signal to add additional delay\n * for load balancer deregistration\n */\nexport async function preStopDelay(ms = 5000): Promise<void> {\n\t// This delay allows the load balancer to detect the unhealthy state\n\t// and stop routing traffic before we start draining connections\n\tawait new Promise((resolve) => setTimeout(resolve, ms));\n}\n","/// <reference types=\"node\" />\n/**\n * Health check utilities for Vreko services\n */\n\nexport interface HealthResponse {\n\tstatus: \"healthy\" | \"degraded\" | \"unhealthy\";\n\ttimestamp: string;\n\tservice: string;\n\tversion?: string;\n\tchecks: {\n\t\t[key: string]: {\n\t\t\tstatus: \"healthy\" | \"degraded\" | \"unhealthy\";\n\t\t\tmessage?: string;\n\t\t\tlatency?: number;\n\t\t\ttimestamp: string;\n\t\t};\n\t};\n\tuptime?: number;\n\tmemoryUsage?: {\n\t\theapUsed: number;\n\t\theapTotal: number;\n\t\trss: number;\n\t};\n}\n\nexport interface HealthCheckOptions {\n\tservice: string;\n\tversion?: string;\n\tdependencies?: Array<{\n\t\tname: string;\n\t\tcheck: () => Promise<{ status: \"healthy\" | \"degraded\" | \"unhealthy\"; message?: string }>;\n\t}>;\n}\n\nexport function createHealthCheck(options: HealthCheckOptions) {\n\treturn async (): Promise<HealthResponse> => {\n\t\tconst checks: HealthResponse[\"checks\"] = {};\n\n\t\t// Add system checks\n\t\tchecks.system = {\n\t\t\tstatus: \"healthy\",\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tlatency: 0,\n\t\t};\n\n\t\t// Check memory usage\n\t\tconst memoryUsage = process.memoryUsage();\n\t\tchecks.memory = {\n\t\t\tstatus: memoryUsage.heapUsed < 0.8 * memoryUsage.heapTotal ? \"healthy\" : \"degraded\",\n\t\t\tmessage: `Memory usage: ${Math.round((memoryUsage.heapUsed / 1024 / 1024) * 100) / 100} MB`,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t};\n\n\t\t// Check uptime\n\t\tconst uptime = process.uptime();\n\n\t\t// Check dependencies if provided\n\t\tif (options.dependencies) {\n\t\t\tfor (const dep of options.dependencies) {\n\t\t\t\ttry {\n\t\t\t\t\tconst depStartTime = Date.now();\n\t\t\t\t\tconst result = await dep.check();\n\t\t\t\t\tconst latency = Date.now() - depStartTime;\n\n\t\t\t\t\tchecks[dep.name] = {\n\t\t\t\t\t\tstatus: result.status,\n\t\t\t\t\t\tmessage: result.message,\n\t\t\t\t\t\tlatency,\n\t\t\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t\t\t};\n\t\t\t\t} catch (error) {\n\t\t\t\t\tchecks[dep.name] = {\n\t\t\t\t\t\tstatus: \"unhealthy\",\n\t\t\t\t\t\tmessage: error instanceof Error ? error.message : \"Unknown error\",\n\t\t\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Determine overall status\n\t\tlet overallStatus: \"healthy\" | \"degraded\" | \"unhealthy\" = \"healthy\";\n\t\tfor (const check of Object.values(checks)) {\n\t\t\tif (check.status === \"unhealthy\") {\n\t\t\t\toverallStatus = \"unhealthy\";\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (check.status === \"degraded\" && overallStatus === \"healthy\") {\n\t\t\t\toverallStatus = \"degraded\";\n\t\t\t}\n\t\t}\n\n\t\tconst response: HealthResponse = {\n\t\t\tstatus: overallStatus,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tservice: options.service,\n\t\t\tchecks,\n\t\t\tuptime,\n\t\t\tmemoryUsage: {\n\t\t\t\theapUsed: memoryUsage.heapUsed,\n\t\t\t\theapTotal: memoryUsage.heapTotal,\n\t\t\t\trss: memoryUsage.rss,\n\t\t\t},\n\t\t};\n\n\t\tif (options.version) {\n\t\t\tresponse.version = options.version;\n\t\t}\n\n\t\treturn response;\n\t};\n}\n\n// Utility function to check database connectivity\nexport async function checkDatabaseConnection(\n\t_connectionString: string,\n): Promise<{ status: \"healthy\" | \"degraded\" | \"unhealthy\"; message?: string }> {\n\ttry {\n\t\t// This is a placeholder - actual implementation would depend on the database driver\n\t\t// For example, with Prisma:\n\t\t// await prisma.$queryRaw`SELECT 1`;\n\n\t\t// For now, we'll simulate a check\n\t\tconst startTime = Date.now();\n\n\t\t// Simulate async operation\n\t\tawait new Promise((resolve) => setTimeout(resolve, Math.random() * 50));\n\n\t\tconst latency = Date.now() - startTime;\n\n\t\tif (latency > 1000) {\n\t\t\treturn {\n\t\t\t\tstatus: \"degraded\",\n\t\t\t\tmessage: `Database connection is slow (${latency}ms)`,\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tstatus: \"healthy\",\n\t\t\tmessage: `Database connection successful (${latency}ms)`,\n\t\t};\n\t} catch (error) {\n\t\treturn {\n\t\t\tstatus: \"unhealthy\",\n\t\t\tmessage: error instanceof Error ? error.message : \"Database connection failed\",\n\t\t};\n\t}\n}\n\n// Utility function to check Redis connectivity\nexport async function checkRedisConnection(\n\t_redisUrl: string,\n): Promise<{ status: \"healthy\" | \"degraded\" | \"unhealthy\"; message?: string }> {\n\ttry {\n\t\t// This is a placeholder - actual implementation would depend on the Redis client\n\t\t// For example, with ioredis:\n\t\t// await redis.ping();\n\n\t\t// Simulate async operation\n\t\tconst startTime = Date.now();\n\t\tawait new Promise((resolve) => setTimeout(resolve, Math.random() * 30));\n\t\tconst latency = Date.now() - startTime;\n\n\t\tif (latency > 200) {\n\t\t\treturn {\n\t\t\t\tstatus: \"degraded\",\n\t\t\t\tmessage: `Redis connection is slow (${latency}ms)`,\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tstatus: \"healthy\",\n\t\t\tmessage: `Redis connection successful (${latency}ms)`,\n\t\t};\n\t} catch (error) {\n\t\treturn {\n\t\t\tstatus: \"unhealthy\",\n\t\t\tmessage: error instanceof Error ? error.message : \"Redis connection failed\",\n\t\t};\n\t}\n}\n\n// Utility function to check HTTP service connectivity\nexport async function checkHttpService(\n\t_url: string,\n): Promise<{ status: \"healthy\" | \"degraded\" | \"unhealthy\"; message?: string }> {\n\ttry {\n\t\t// This is a placeholder - actual implementation would use fetch or axios\n\t\t// For example:\n\t\t// const response = await fetch(url, { timeout: 5000 });\n\n\t\t// Simulate async operation\n\t\tconst startTime = Date.now();\n\t\tawait new Promise((resolve) => setTimeout(resolve, Math.random() * 100));\n\t\tconst latency = Date.now() - startTime;\n\n\t\tif (latency > 1000) {\n\t\t\treturn {\n\t\t\t\tstatus: \"degraded\",\n\t\t\t\tmessage: `HTTP service is slow (${latency}ms)`,\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tstatus: \"healthy\",\n\t\t\tmessage: `HTTP service check successful (${latency}ms)`,\n\t\t};\n\t} catch (error) {\n\t\treturn {\n\t\t\tstatus: \"unhealthy\",\n\t\t\tmessage: error instanceof Error ? error.message : \"HTTP service check failed\",\n\t\t};\n\t}\n}\n","/**\n * Analytics Events - Complete Event Taxonomy\n *\n * Type-safe event definitions for Vreko analytics.\n * Aligned with PostHog best practices and TDD strategy.\n */\n\n// ============================================================================\n// EVENT DEFINITIONS\n// ============================================================================\n\nexport const AnalyticsEvents = {\n\t// ===== Authentication Events (6) =====\n\tAUTH_SIGNUP_COMPLETED: \"auth_signup_completed\",\n\tAUTH_LOGIN_COMPLETED: \"auth_login_completed\",\n\tAUTH_LOGOUT_COMPLETED: \"auth_logout_completed\",\n\tAUTH_EMAIL_VERIFIED: \"auth_email_verified\",\n\tAUTH_PASSWORD_RESET_REQUESTED: \"auth_password_reset_requested\",\n\tAUTH_PASSWORD_RESET_COMPLETED: \"auth_password_reset_completed\",\n\n\t// ===== Snapshot Events (20) =====\n\tSNAPSHOT_CREATED: \"snapshot_created\",\n\tSNAPSHOT_RESTORED: \"snapshot_restored\",\n\tSNAPSHOT_DELETED: \"snapshot_deleted\",\n\tSNAPSHOT_SEARCHED: \"snapshot_searched\",\n\tSNAPSHOT_LIMIT_HIT: \"snapshot_limit_hit\",\n\tSNAPSHOT_AUTO_CREATED: \"snapshot_auto_created\",\n\tSNAPSHOT_SHARED: \"snapshot_shared\",\n\tSNAPSHOT_EXPORTED: \"snapshot_exported\",\n\tSNAPSHOT_VIEWED: \"snapshot_viewed\",\n\tSNAPSHOT_DIFF_VIEWED: \"snapshot_diff_viewed\",\n\t// Removed duplicate snapshot_checkpoint_* events to maintain consistent terminology\n\n\t// ===== Billing/Monetization Events (12) =====\n\tBILLING_UPGRADE_PROMPT_SHOWN: \"billing_upgrade_prompt_shown\",\n\tBILLING_UPGRADE_PROMPT_CLICKED: \"billing_upgrade_prompt_clicked\",\n\tBILLING_PRICING_VIEWED: \"billing_pricing_viewed\",\n\tBILLING_CHECKOUT_STARTED: \"billing_checkout_started\",\n\tBILLING_CHECKOUT_COMPLETED: \"billing_checkout_completed\",\n\tBILLING_CHECKOUT_ABANDONED: \"billing_checkout_abandoned\",\n\tBILLING_SUBSCRIPTION_UPGRADED: \"billing_subscription_upgraded\",\n\tBILLING_SUBSCRIPTION_DOWNGRADED: \"billing_subscription_downgraded\",\n\tBILLING_SUBSCRIPTION_CANCELLED: \"billing_subscription_cancelled\",\n\tBILLING_PAYMENT_FAILED: \"billing_payment_failed\",\n\tBILLING_COUPON_APPLIED: \"billing_coupon_applied\",\n\tBILLING_INVOICE_VIEWED: \"billing_invoice_viewed\",\n\n\t// ===== Extension Events (8) =====\n\tEXTENSION_INSTALLED: \"extension_installed\",\n\tEXTENSION_ACTIVATED: \"extension_activated\",\n\tEXTENSION_COMMAND_USED: \"extension_command_used\",\n\tEXTENSION_SETTINGS_CHANGED: \"extension_settings_changed\",\n\tEXTENSION_ERROR_OCCURRED: \"extension_error_occurred\",\n\tEXTENSION_UPDATED: \"extension_updated\",\n\tEXTENSION_UNINSTALLED: \"extension_uninstalled\",\n\tEXTENSION_FEEDBACK_SUBMITTED: \"extension_feedback_submitted\",\n\n\t// ===== Dashboard Events (8) =====\n\tDASHBOARD_VIEWED: \"dashboard_viewed\",\n\tDASHBOARD_API_KEY_CREATED: \"dashboard_api_key_created\",\n\tDASHBOARD_API_KEY_REVOKED: \"dashboard_api_key_revoked\",\n\tDASHBOARD_USAGE_CHART_VIEWED: \"dashboard_usage_chart_viewed\",\n\tDASHBOARD_SETTINGS_UPDATED: \"dashboard_settings_updated\",\n\tDASHBOARD_SEARCH_PERFORMED: \"dashboard_search_performed\",\n\tDASHBOARD_EXPORT_TRIGGERED: \"dashboard_export_triggered\",\n\tDASHBOARD_HELP_ACCESSED: \"dashboard_help_accessed\",\n\n\t// ===== Team Collaboration Events (6) =====\n\tTEAM_CREATED: \"team_created\",\n\tTEAM_MEMBER_INVITED: \"team_member_invited\",\n\tTEAM_MEMBER_JOINED: \"team_member_joined\",\n\tTEAM_SNAPSHOT_SHARED: \"team_snapshot_shared\",\n\tTEAM_SETTINGS_CHANGED: \"team_settings_changed\",\n\tTEAM_MEMBER_REMOVED: \"team_member_removed\",\n\n\t// ===== AI Features Events (5) =====\n\tAI_SUGGESTION_SHOWN: \"ai_suggestion_shown\",\n\tAI_SUGGESTION_ACCEPTED: \"ai_suggestion_accepted\",\n\tAI_SUGGESTION_REJECTED: \"ai_suggestion_rejected\",\n\tAI_RISK_DETECTED: \"ai_risk_detected\",\n\tAI_RISK_PREVENTED: \"ai_risk_prevented\",\n\n\t// ===== API Usage Events (5) =====\n\tAPI_CALL_MADE: \"api_call_made\",\n\tAPI_RATE_LIMIT_HIT: \"api_rate_limit_hit\",\n\tAPI_ERROR_OCCURRED: \"api_error_occurred\",\n\tAPI_KEY_ROTATED: \"api_key_rotated\",\n\tAPI_WEBHOOK_CONFIGURED: \"api_webhook_configured\",\n\n\t// ===== Intelligence Layer: Prediction & Learning (6) =====\n\tPREDICTION_MADE: \"prediction_made\",\n\tPREDICTION_OUTCOME_RECORDED: \"prediction_outcome_recorded\",\n\tTRUST_SCORE_UPDATED: \"trust_score_updated\",\n\tPATTERN_DETECTED: \"pattern_detected\",\n\tPATTERN_CONFIRMED: \"pattern_confirmed\",\n\tMODEL_CALIBRATION_TRIGGERED: \"model_calibration_triggered\",\n\n\t// ===== Intelligence Layer: Cross-Repo Intelligence (4) =====\n\tWORKSPACE_CONNECTED: \"workspace_connected\",\n\tCROSS_REPO_PATTERN_DETECTED: \"cross_repo_pattern_detected\",\n\tREPO_PERSONALITY_UPDATED: \"repo_personality_updated\",\n\tGLOBAL_INSIGHT_APPLIED: \"global_insight_applied\",\n\n\t// ===== Intelligence Layer: GitHub Integration (5) =====\n\tGITHUB_REPO_CONNECTED: \"github_repo_connected\",\n\tGITHUB_PR_ANALYZED: \"github_pr_analyzed\",\n\tGITHUB_COMMIT_SCANNED: \"github_commit_scanned\",\n\tGITHUB_AI_CONTRIBUTION_DETECTED: \"github_ai_contribution_detected\",\n\tGITHUB_CHECK_POSTED: \"github_check_posted\",\n\n\t// ===== Intelligence Layer: MCP Tools (3) =====\n\tMCP_TOOL_CALLED: \"mcp_tool_called\",\n\tMCP_CONTEXT_PROVIDED: \"mcp_context_provided\",\n\tMCP_AGENT_SELF_CHECK: \"mcp_agent_self_check\",\n\n\t// ===== Intelligence Layer: Community & Engagement (6) =====\n\tDISASTER_STORY_SHARED: \"disaster_story_shared\",\n\tFEEDBACK_SUBMITTED: \"feedback_submitted\",\n\tCOMMUNITY_ACTION_COMPLETED: \"community_action_completed\",\n\tBETA_ELIGIBILITY_CALCULATED: \"beta_eligibility_calculated\",\n\tREFERRAL_LINK_GENERATED: \"referral_link_generated\",\n\tREFERRAL_CONVERTED: \"referral_converted\",\n\n\t// ===== Activation Funnel Events (2) =====\n\tAUTH_COMPLETED: \"auth_completed\",\n\tFIRST_SNAPSHOT_CREATED: \"first_snapshot_created\",\n} as const;\n\nexport type AnalyticsEvent = (typeof AnalyticsEvents)[keyof typeof AnalyticsEvents];\n\n// ============================================================================\n// BASE PROPERTIES (Auto-enriched)\n// ============================================================================\n\nexport interface BaseEventProperties {\n\t// Auto-enriched by analytics service\n\tplan?: \"free\" | \"pro\" | \"team\" | \"enterprise\";\n\tenvironment?: \"extension\" | \"web\" | \"api\" | \"cli\";\n\tversion?: string;\n\ttimestamp?: string;\n}\n\n// ============================================================================\n// EVENT PROPERTY INTERFACES\n// ============================================================================\n\n// ----- Authentication Events -----\n\nexport interface AuthSignupCompletedProps extends BaseEventProperties {\n\tsignup_method: \"email\" | \"google\" | \"github\";\n\treferrer: string | null;\n\tutm_source?: string;\n\tutm_campaign?: string;\n\tutm_medium?: string;\n}\n\nexport interface AuthLoginCompletedProps extends BaseEventProperties {\n\tlogin_method: \"email\" | \"google\" | \"github\";\n\tis_new_session: boolean;\n}\n\nexport interface AuthLogoutCompletedProps extends BaseEventProperties {\n\tsession_duration_seconds: number;\n}\n\nexport interface AuthEmailVerifiedProps extends BaseEventProperties {\n\ttime_to_verify_minutes: number;\n}\n\nexport interface AuthPasswordResetRequestedProps extends BaseEventProperties {\n\temail: string;\n}\n\nexport interface AuthPasswordResetCompletedProps extends BaseEventProperties {\n\ttime_from_request_minutes: number;\n}\n\n// ----- Snapshot Events -----\n\nexport interface SnapshotCreatedProps extends BaseEventProperties {\n\tfile_extension: string;\n\tfile_size_bytes: number;\n\thas_message: boolean;\n\ttrigger: \"manual\" | \"auto\" | \"ai_suggestion\";\n\tenvironment: \"extension\" | \"cli\";\n}\n\nexport interface SnapshotRestoredProps extends BaseEventProperties {\n\tsnapshot_age_minutes: number;\n\tfile_extension: string;\n\trestore_method: \"click\" | \"keyboard\" | \"command_palette\";\n\twas_successful: boolean;\n}\n\nexport interface SnapshotDeletedProps extends BaseEventProperties {\n\tsnapshot_age_days: number;\n\tdelete_method: \"single\" | \"bulk\";\n}\n\nexport interface SnapshotSearchedProps extends BaseEventProperties {\n\tquery_length: number;\n\tresults_count: number;\n\tfilter_used: boolean;\n}\n\nexport interface SnapshotLimitHitProps extends BaseEventProperties {\n\tcurrent_count: number;\n\tplan_limit: number;\n\tupgrade_prompt_shown: boolean;\n}\n\nexport interface SnapshotAutoCreatedProps extends BaseEventProperties {\n\tai_confidence: number; // 0-1\n\trisk_score: number; // 0-100\n\treason: \"dangerous_operation\" | \"merge_conflict\" | \"api_response\";\n}\n\nexport interface SnapshotSharedProps extends BaseEventProperties {\n\tshare_method: \"link\" | \"email\" | \"slack\";\n\trecipient_count: number;\n}\n\nexport interface SnapshotExportedProps extends BaseEventProperties {\n\texport_format: \"json\" | \"zip\" | \"git_patch\";\n\tsnapshot_count: number;\n}\n\nexport interface SnapshotViewedProps extends BaseEventProperties {\n\tview_location: \"dashboard\" | \"extension\" | \"api\";\n\tsnapshot_age_days: number;\n}\n\nexport interface SnapshotDiffViewedProps extends BaseEventProperties {\n\tlines_added: number;\n\tlines_removed: number;\n\thas_conflicts: boolean;\n}\n\n// ----- Billing Events -----\n\nexport interface BillingUpgradePromptShownProps extends BaseEventProperties {\n\ttrigger: \"storage_limit\" | \"team_detection\" | \"feature_lock\" | \"manual\";\n\tprompt_location: \"extension\" | \"dashboard\" | \"api_response\";\n\tcurrent_usage_percent: number;\n}\n\nexport interface BillingUpgradePromptClickedProps extends BaseEventProperties {\n\ttrigger: string;\n\tprompt_location: string;\n\ttime_to_click_seconds: number;\n}\n\nexport interface BillingPricingViewedProps extends BaseEventProperties {\n\treferrer: string | null;\n\tcurrent_plan: string;\n}\n\nexport interface BillingCheckoutStartedProps extends BaseEventProperties {\n\tplan_selected: \"pro\" | \"team\" | \"enterprise\";\n\tbilling_cycle: \"monthly\" | \"yearly\";\n\tprice_usd: number;\n}\n\nexport interface BillingCheckoutCompletedProps extends BaseEventProperties {\n\tplan: \"pro\" | \"team\" | \"enterprise\";\n\tbilling_cycle: \"monthly\" | \"yearly\";\n\tprice_usd: number;\n\ttime_to_convert_minutes: number;\n\tcoupon_used: string | null;\n}\n\nexport interface BillingCheckoutAbandonedProps extends BaseEventProperties {\n\tplan_attempted: string;\n\tcheckout_step: \"payment_info\" | \"review\" | \"processing\";\n\ttime_spent_seconds: number;\n}\n\nexport interface BillingSubscriptionUpgradedProps extends BaseEventProperties {\n\tfrom_plan: string;\n\tto_plan: string;\n\tprice_increase_usd: number;\n}\n\nexport interface BillingSubscriptionDowngradedProps extends BaseEventProperties {\n\tfrom_plan: string;\n\tto_plan: string;\n\treason: string | null;\n}\n\nexport interface BillingSubscriptionCancelledProps extends Omit<BaseEventProperties, \"plan\"> {\n\tplan: string;\n\tcancellation_reason: string;\n\twas_prompted_to_stay: boolean;\n\tstayed: boolean;\n}\n\nexport interface BillingPaymentFailedProps extends Omit<BaseEventProperties, \"plan\"> {\n\tplan: string;\n\terror_code: string;\n\tretry_count: number;\n}\n\nexport interface BillingCouponAppliedProps extends Omit<BaseEventProperties, \"plan\"> {\n\tcoupon_code: string;\n\tdiscount_percent: number;\n\tplan: string;\n}\n\nexport interface BillingInvoiceViewedProps extends BaseEventProperties {\n\tinvoice_date: string;\n\tamount_usd: number;\n}\n\n// ----- Extension Events -----\n\nexport interface ExtensionInstalledProps extends BaseEventProperties {\n\tversion: string;\n\tvscode_version: string;\n\tos: \"windows\" | \"mac\" | \"linux\";\n\tinstall_source: \"marketplace\" | \"direct\" | \"referral\";\n}\n\nexport interface ExtensionActivatedProps extends BaseEventProperties {\n\ttime_since_install_minutes: number;\n\tworkspace_type: \"single\" | \"multi\";\n}\n\nexport interface ExtensionCommandUsedProps extends BaseEventProperties {\n\tcommand: string;\n\ttrigger_method: \"keyboard\" | \"command_palette\" | \"context_menu\";\n}\n\nexport interface ExtensionSettingsChangedProps extends BaseEventProperties {\n\tsetting_key: string;\n\told_value: string | number | boolean;\n\tnew_value: string | number | boolean;\n}\n\nexport interface ExtensionErrorOccurredProps extends BaseEventProperties {\n\terror_type: string;\n\terror_message: string;\n\tstack_trace: string;\n\tfile_context: string | null;\n}\n\nexport interface ExtensionUpdatedProps extends BaseEventProperties {\n\tfrom_version: string;\n\tto_version: string;\n\tupdate_type: \"major\" | \"minor\" | \"patch\";\n}\n\nexport interface ExtensionUninstalledProps extends BaseEventProperties {\n\tdays_since_install: number;\n\ttotal_snapshots_created: number;\n\treason: string | null;\n}\n\nexport interface ExtensionFeedbackSubmittedProps extends BaseEventProperties {\n\trating: 1 | 2 | 3 | 4 | 5;\n\tfeedback_text_length: number;\n\tfeedback_category: string;\n}\n\n// ----- Dashboard Events -----\n\nexport interface DashboardViewedProps extends BaseEventProperties {\n\tpage: \"overview\" | \"snapshots\" | \"usage\" | \"settings\" | \"billing\";\n\treferrer: string | null;\n}\n\nexport interface DashboardApiKeyCreatedProps extends BaseEventProperties {\n\tkey_name: string;\n\tkey_type: \"production\" | \"test\";\n}\n\nexport interface DashboardApiKeyRevokedProps extends BaseEventProperties {\n\tkey_age_days: number;\n\twas_ever_used: boolean;\n}\n\nexport interface DashboardUsageChartViewedProps extends BaseEventProperties {\n\ttime_range: \"7d\" | \"30d\" | \"90d\" | \"custom\";\n\tchart_type: \"line\" | \"bar\";\n}\n\nexport interface DashboardSettingsUpdatedProps extends BaseEventProperties {\n\tsettings_changed: string[];\n}\n\nexport interface DashboardSearchPerformedProps extends BaseEventProperties {\n\tquery: string; // Hashed for privacy\n\tresults_count: number;\n\tsearch_location: \"snapshots\" | \"files\" | \"global\";\n}\n\nexport interface DashboardExportTriggeredProps extends BaseEventProperties {\n\texport_type: \"snapshots\" | \"usage_data\" | \"invoice\";\n\tformat: \"csv\" | \"json\" | \"pdf\";\n}\n\nexport interface DashboardHelpAccessedProps extends BaseEventProperties {\n\tdoc_page: string;\n\taccess_method: \"search\" | \"link\" | \"navigation\";\n}\n\n// ----- Team Events -----\n\nexport interface TeamCreatedProps extends BaseEventProperties {\n\tteam_size: number;\n\tplan: \"team\" | \"enterprise\";\n}\n\nexport interface TeamMemberInvitedProps extends BaseEventProperties {\n\trole: \"admin\" | \"member\" | \"viewer\";\n\tinvitation_method: \"email\" | \"link\";\n}\n\nexport interface TeamMemberJoinedProps extends BaseEventProperties {\n\ttime_to_join_hours: number;\n\trole: string;\n}\n\nexport interface TeamSnapshotSharedProps extends BaseEventProperties {\n\trecipient_count: number;\n\tshare_method: \"internal\" | \"external_link\";\n}\n\nexport interface TeamSettingsChangedProps extends BaseEventProperties {\n\tsetting_key: string;\n\tchanged_by_role: \"owner\" | \"admin\";\n}\n\nexport interface TeamMemberRemovedProps extends BaseEventProperties {\n\tmember_tenure_days: number;\n\tremoval_reason: \"voluntary\" | \"involuntary\";\n}\n\n// ----- AI Features Events -----\n\nexport interface AiSuggestionShownProps extends BaseEventProperties {\n\tsuggestion_type: \"snapshot\" | \"restore\" | \"cleanup\";\n\tconfidence_score: number; // 0-1\n\tcontext: string;\n}\n\nexport interface AiSuggestionAcceptedProps extends BaseEventProperties {\n\tsuggestion_type: string;\n\tconfidence_score: number;\n\ttime_to_accept_seconds: number;\n}\n\nexport interface AiSuggestionRejectedProps extends BaseEventProperties {\n\tsuggestion_type: string;\n\trejection_reason: string | null;\n}\n\nexport interface AiRiskDetectedProps extends BaseEventProperties {\n\trisk_type: \"security\" | \"performance\" | \"breaking_change\";\n\trisk_score: number; // 0-100\n\twas_prevented: boolean;\n}\n\nexport interface AiRiskPreventedProps extends BaseEventProperties {\n\trisk_type: string;\n\trisk_score: number;\n\tsnapshot_created: boolean;\n}\n\n// ----- API Usage Events -----\n\nexport interface ApiCallMadeProps extends BaseEventProperties {\n\tendpoint: string;\n\tmethod: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\";\n\tresponse_time_ms: number;\n\tstatus_code: number;\n}\n\nexport interface ApiRateLimitHitProps extends BaseEventProperties {\n\tendpoint: string;\n\tlimit_type: \"per_minute\" | \"per_hour\" | \"per_day\";\n\tcurrent_plan: string;\n}\n\nexport interface ApiErrorOccurredProps extends BaseEventProperties {\n\tendpoint: string;\n\terror_code: string;\n\terror_message: string;\n}\n\nexport interface ApiKeyRotatedProps extends BaseEventProperties {\n\told_key_age_days: number;\n\trotation_reason: \"scheduled\" | \"security\" | \"manual\";\n}\n\nexport interface ApiWebhookConfiguredProps extends BaseEventProperties {\n\twebhook_url: string; // Hashed for privacy\n\tevent_types: string[];\n}\n\n// ----- Activation Funnel Events -----\n\nexport interface AuthCompletedProps extends BaseEventProperties {\n\tauth_method: \"email\" | \"google\" | \"github\";\n\ttime_to_auth_minutes: number;\n}\n\nexport interface FirstSnapshotCreatedProps extends BaseEventProperties {\n\tsnapshot_method: \"manual\" | \"auto\";\n\tfiles_count: number;\n\ttime_to_first_snapshot_minutes: number;\n}\n\n// ----- Intelligence Layer: Prediction & Learning -----\n\nexport interface PredictionMadeProps extends BaseEventProperties {\n\tsession_id: string;\n\tprediction_type: \"risk_level\" | \"will_need_recovery\" | \"ai_tool_confidence\";\n\tpredicted_value: number;\n\tmodel_version: string;\n\tfeatures_used: string[];\n\tcontext_hash: string; // Anonymized context identifier\n}\n\nexport interface PredictionOutcomeRecordedProps extends BaseEventProperties {\n\tsession_id: string;\n\tprediction_id: string;\n\tpredicted_value: number;\n\tactual_outcome: boolean;\n\twas_correct: boolean;\n\ttime_to_feedback_ms: number;\n\toutcome_source: \"user_action\" | \"build_result\" | \"recovery_triggered\";\n}\n\nexport interface TrustScoreUpdatedProps extends BaseEventProperties {\n\ttool_id: string; // e.g., 'cursor_0.42', 'copilot_1.2'\n\tcontext_key: string; // e.g., 'react_typescript_refactor'\n\told_score: number;\n\tnew_score: number;\n\tadjustment_reason: \"success\" | \"failure\" | \"near_miss\" | \"decay\";\n\tsample_size: number; // How many outcomes informed this\n}\n\nexport interface PatternDetectedProps extends BaseEventProperties {\n\tpattern_signature: string;\n\tpattern_type: \"dangerous\" | \"beneficial\" | \"neutral\";\n\tsimilarity_score: number;\n\tfile_types: string[];\n\ttool_affinity: string[];\n}\n\nexport interface PatternConfirmedProps extends BaseEventProperties {\n\tpattern_id: string;\n\tconfirmation_source: \"user_feedback\" | \"recovery_avoided\" | \"incident_occurred\";\n\tprevious_success_rate: number;\n\tnew_success_rate: number;\n}\n\nexport interface ModelCalibrationTriggeredProps extends BaseEventProperties {\n\tcalibration_reason: \"scheduled\" | \"accuracy_drop\" | \"new_data_threshold\";\n\tmodel_version: string;\n\tsamples_used: number;\n\taccuracy_before: number;\n\taccuracy_after: number;\n}\n\n// ----- Intelligence Layer: Cross-Repo Intelligence -----\n\nexport interface WorkspaceConnectedProps extends BaseEventProperties {\n\trepo_count: number;\n\tprimary_language: string;\n\tframework_detected: string[];\n}\n\nexport interface CrossRepoPatternDetectedProps extends BaseEventProperties {\n\tpattern_signature: string;\n\toccurrence_count: number; // Across how many repos\n\tsuccess_rate: number;\n\trepos_affected: number; // Privacy: count only, no repo IDs\n}\n\nexport interface RepoPersonalityUpdatedProps extends BaseEventProperties {\n\trepo_id: string; // Hashed\n\tai_tolerance: number;\n\tvolatility: number;\n\trisk_profile: \"production\" | \"experimental\" | \"stable\";\n\tincident_count: number;\n}\n\nexport interface GlobalInsightAppliedProps extends BaseEventProperties {\n\tinsight_type: \"pattern_warning\" | \"trust_adjustment\" | \"risk_prediction\";\n\tsource: \"community_pattern\" | \"similar_repo\" | \"framework_best_practice\";\n\tconfidence: number;\n}\n\n// ----- Intelligence Layer: GitHub Integration -----\n\nexport interface GithubRepoConnectedProps extends BaseEventProperties {\n\trepo_id: string; // Hashed\n\torganization_id: string; // Hashed\n\tpermissions: string[];\n\twebhook_configured: boolean;\n}\n\nexport interface GithubPrAnalyzedProps extends BaseEventProperties {\n\tpr_number: number;\n\trepo_id: string; // Hashed\n\trisk_score: number;\n\tai_contribution_percentage: number;\n\tfiles_changed: number;\n\tlines_added: number;\n\tlines_removed: number;\n\testimated_ai_tool: string | null;\n\tpatterns_detected: string[];\n\tcheck_conclusion: \"success\" | \"neutral\" | \"failure\";\n}\n\nexport interface GithubCommitScannedProps extends BaseEventProperties {\n\tcommit_hash: string; // Partial hash\n\trepo_id: string; // Hashed\n\thas_co_author_tag: boolean;\n\tdetected_ai_tool: string | null;\n\tanalysis_method: \"co_author_tag\" | \"stylistic_analysis\" | \"burst_pattern\";\n}\n\nexport interface GithubAiContributionDetectedProps extends BaseEventProperties {\n\tcommit_hash: string; // Partial\n\trepo_id: string; // Hashed\n\tdetection_method: \"co_author_tag\" | \"stylistic_analysis\" | \"burst_pattern\";\n\tconfidence: number;\n\ttool_identified: string | null;\n\tfed_to_calibration: boolean;\n}\n\nexport interface GithubCheckPostedProps extends BaseEventProperties {\n\tpr_number: number;\n\trepo_id: string; // Hashed\n\tcheck_status: \"queued\" | \"in_progress\" | \"completed\";\n\tconclusion: \"success\" | \"neutral\" | \"failure\" | null;\n\trisk_score_displayed: number;\n}\n\n// ----- Intelligence Layer: MCP Tools -----\n\nexport interface McpToolCalledProps extends BaseEventProperties {\n\ttool_name: string;\n\tclient_type: \"vscode\" | \"jetbrains\" | \"cli\" | \"api\";\n\tparameters: Record<string, unknown>; // Sanitized\n\texecution_time_ms: number;\n\twas_successful: boolean;\n}\n\nexport interface McpContextProvidedProps extends BaseEventProperties {\n\tcontext_type: \"checkpoint_history\" | \"risk_analysis\" | \"protection_status\";\n\tcontext_size_bytes: number;\n\trequest_source: \"ai_agent\" | \"user_query\";\n}\n\nexport interface McpAgentSelfCheckProps extends BaseEventProperties {\n\tagent_type: string;\n\trecovery_count_this_repo: number;\n\tself_adjustment_made: boolean;\n\tnew_behavior_pattern: string | null;\n}\n\n// ----- Intelligence Layer: Community & Engagement -----\n\nexport interface DisasterStorySharedProps extends BaseEventProperties {\n\tstory_category: \"recovery_saved_me\" | \"ai_mistake\" | \"near_miss\";\n\timpact_severity: \"low\" | \"medium\" | \"high\" | \"critical\";\n\tshared_publicly: boolean;\n}\n\nexport interface FeedbackSubmittedProps extends BaseEventProperties {\n\tfeedback_type: \"bug_report\" | \"feature_request\" | \"general\";\n\tfeedback_quality_score: number; // Internal scoring\n\tincludes_reproduction_steps: boolean;\n}\n\nexport interface CommunityActionCompletedProps extends BaseEventProperties {\n\taction_type:\n\t\t| \"github_star\"\n\t\t| \"github_issue_opened\"\n\t\t| \"github_pr_submitted\"\n\t\t| \"discord_joined\"\n\t\t| \"discord_question_answered\"\n\t\t| \"social_share\"\n\t\t| \"marketplace_review\"\n\t\t| \"disaster_story_shared\"\n\t\t| \"feedback_submitted\";\n\tpoints_earned: number;\n\ttier_progress_before: number;\n\ttier_progress_after: number;\n\tengagement_score_delta: number;\n}\n\nexport interface BetaEligibilityCalculatedProps extends BaseEventProperties {\n\ttotal_engagement_score: number;\n\tusage_score: number;\n\tfeedback_quality_score: number;\n\tcommunity_score: number;\n\treferral_score: number;\n\tbeta_tier_unlocked: \"none\" | \"early_access\" | \"beta\" | \"lifetime_free\";\n\tqualifying_actions: string[];\n}\n\nexport interface ReferralLinkGeneratedProps extends BaseEventProperties {\n\treferral_code: string; // Hashed\n\tcampaign: string | null;\n}\n\nexport interface ReferralConvertedProps extends BaseEventProperties {\n\treferrer_id: string; // Hashed\n\treferred_id: string; // Hashed\n\tconversion_time_hours: number;\n\treferral_reward: string;\n}\n\n// ============================================================================\n// EVENT PROPERTIES MAP (Type-safe mapping)\n// ============================================================================\n\nexport interface EventPropertiesMap {\n\t// Authentication\n\t[AnalyticsEvents.AUTH_SIGNUP_COMPLETED]: AuthSignupCompletedProps;\n\t[AnalyticsEvents.AUTH_LOGIN_COMPLETED]: AuthLoginCompletedProps;\n\t[AnalyticsEvents.AUTH_LOGOUT_COMPLETED]: AuthLogoutCompletedProps;\n\t[AnalyticsEvents.AUTH_EMAIL_VERIFIED]: AuthEmailVerifiedProps;\n\t[AnalyticsEvents.AUTH_PASSWORD_RESET_REQUESTED]: AuthPasswordResetRequestedProps;\n\t[AnalyticsEvents.AUTH_PASSWORD_RESET_COMPLETED]: AuthPasswordResetCompletedProps;\n\n\t// Snapshots\n\t[AnalyticsEvents.SNAPSHOT_CREATED]: SnapshotCreatedProps;\n\t[AnalyticsEvents.SNAPSHOT_RESTORED]: SnapshotRestoredProps;\n\t[AnalyticsEvents.SNAPSHOT_DELETED]: SnapshotDeletedProps;\n\t[AnalyticsEvents.SNAPSHOT_SEARCHED]: SnapshotSearchedProps;\n\t[AnalyticsEvents.SNAPSHOT_LIMIT_HIT]: SnapshotLimitHitProps;\n\t[AnalyticsEvents.SNAPSHOT_AUTO_CREATED]: SnapshotAutoCreatedProps;\n\t[AnalyticsEvents.SNAPSHOT_SHARED]: SnapshotSharedProps;\n\t[AnalyticsEvents.SNAPSHOT_EXPORTED]: SnapshotExportedProps;\n\t[AnalyticsEvents.SNAPSHOT_VIEWED]: SnapshotViewedProps;\n\t[AnalyticsEvents.SNAPSHOT_DIFF_VIEWED]: SnapshotDiffViewedProps;\n\n\t// Billing\n\t[AnalyticsEvents.BILLING_UPGRADE_PROMPT_SHOWN]: BillingUpgradePromptShownProps;\n\t[AnalyticsEvents.BILLING_UPGRADE_PROMPT_CLICKED]: BillingUpgradePromptClickedProps;\n\t[AnalyticsEvents.BILLING_PRICING_VIEWED]: BillingPricingViewedProps;\n\t[AnalyticsEvents.BILLING_CHECKOUT_STARTED]: BillingCheckoutStartedProps;\n\t[AnalyticsEvents.BILLING_CHECKOUT_COMPLETED]: BillingCheckoutCompletedProps;\n\t[AnalyticsEvents.BILLING_CHECKOUT_ABANDONED]: BillingCheckoutAbandonedProps;\n\t[AnalyticsEvents.BILLING_SUBSCRIPTION_UPGRADED]: BillingSubscriptionUpgradedProps;\n\t[AnalyticsEvents.BILLING_SUBSCRIPTION_DOWNGRADED]: BillingSubscriptionDowngradedProps;\n\t[AnalyticsEvents.BILLING_SUBSCRIPTION_CANCELLED]: BillingSubscriptionCancelledProps;\n\t[AnalyticsEvents.BILLING_PAYMENT_FAILED]: BillingPaymentFailedProps;\n\t[AnalyticsEvents.BILLING_COUPON_APPLIED]: BillingCouponAppliedProps;\n\t[AnalyticsEvents.BILLING_INVOICE_VIEWED]: BillingInvoiceViewedProps;\n\n\t// Extension\n\t[AnalyticsEvents.EXTENSION_INSTALLED]: ExtensionInstalledProps;\n\t[AnalyticsEvents.EXTENSION_ACTIVATED]: ExtensionActivatedProps;\n\t[AnalyticsEvents.EXTENSION_COMMAND_USED]: ExtensionCommandUsedProps;\n\t[AnalyticsEvents.EXTENSION_SETTINGS_CHANGED]: ExtensionSettingsChangedProps;\n\t[AnalyticsEvents.EXTENSION_ERROR_OCCURRED]: ExtensionErrorOccurredProps;\n\t[AnalyticsEvents.EXTENSION_UPDATED]: ExtensionUpdatedProps;\n\t[AnalyticsEvents.EXTENSION_UNINSTALLED]: ExtensionUninstalledProps;\n\t[AnalyticsEvents.EXTENSION_FEEDBACK_SUBMITTED]: ExtensionFeedbackSubmittedProps;\n\n\t// Dashboard\n\t[AnalyticsEvents.DASHBOARD_VIEWED]: DashboardViewedProps;\n\t[AnalyticsEvents.DASHBOARD_API_KEY_CREATED]: DashboardApiKeyCreatedProps;\n\t[AnalyticsEvents.DASHBOARD_API_KEY_REVOKED]: DashboardApiKeyRevokedProps;\n\t[AnalyticsEvents.DASHBOARD_USAGE_CHART_VIEWED]: DashboardUsageChartViewedProps;\n\t[AnalyticsEvents.DASHBOARD_SETTINGS_UPDATED]: DashboardSettingsUpdatedProps;\n\t[AnalyticsEvents.DASHBOARD_SEARCH_PERFORMED]: DashboardSearchPerformedProps;\n\t[AnalyticsEvents.DASHBOARD_EXPORT_TRIGGERED]: DashboardExportTriggeredProps;\n\t[AnalyticsEvents.DASHBOARD_HELP_ACCESSED]: DashboardHelpAccessedProps;\n\n\t// Team\n\t[AnalyticsEvents.TEAM_CREATED]: TeamCreatedProps;\n\t[AnalyticsEvents.TEAM_MEMBER_INVITED]: TeamMemberInvitedProps;\n\t[AnalyticsEvents.TEAM_MEMBER_JOINED]: TeamMemberJoinedProps;\n\t[AnalyticsEvents.TEAM_SNAPSHOT_SHARED]: TeamSnapshotSharedProps;\n\t[AnalyticsEvents.TEAM_SETTINGS_CHANGED]: TeamSettingsChangedProps;\n\t[AnalyticsEvents.TEAM_MEMBER_REMOVED]: TeamMemberRemovedProps;\n\n\t// AI Features\n\t[AnalyticsEvents.AI_SUGGESTION_SHOWN]: AiSuggestionShownProps;\n\t[AnalyticsEvents.AI_SUGGESTION_ACCEPTED]: AiSuggestionAcceptedProps;\n\t[AnalyticsEvents.AI_SUGGESTION_REJECTED]: AiSuggestionRejectedProps;\n\t[AnalyticsEvents.AI_RISK_DETECTED]: AiRiskDetectedProps;\n\t[AnalyticsEvents.AI_RISK_PREVENTED]: AiRiskPreventedProps;\n\n\t// API Usage\n\t[AnalyticsEvents.API_CALL_MADE]: ApiCallMadeProps;\n\t[AnalyticsEvents.API_RATE_LIMIT_HIT]: ApiRateLimitHitProps;\n\t[AnalyticsEvents.API_ERROR_OCCURRED]: ApiErrorOccurredProps;\n\t[AnalyticsEvents.API_KEY_ROTATED]: ApiKeyRotatedProps;\n\t[AnalyticsEvents.API_WEBHOOK_CONFIGURED]: ApiWebhookConfiguredProps;\n\n\t// Intelligence Layer: Prediction & Learning\n\t[AnalyticsEvents.PREDICTION_MADE]: PredictionMadeProps;\n\t[AnalyticsEvents.PREDICTION_OUTCOME_RECORDED]: PredictionOutcomeRecordedProps;\n\t[AnalyticsEvents.TRUST_SCORE_UPDATED]: TrustScoreUpdatedProps;\n\t[AnalyticsEvents.PATTERN_DETECTED]: PatternDetectedProps;\n\t[AnalyticsEvents.PATTERN_CONFIRMED]: PatternConfirmedProps;\n\t[AnalyticsEvents.MODEL_CALIBRATION_TRIGGERED]: ModelCalibrationTriggeredProps;\n\n\t// Intelligence Layer: Cross-Repo Intelligence\n\t[AnalyticsEvents.WORKSPACE_CONNECTED]: WorkspaceConnectedProps;\n\t[AnalyticsEvents.CROSS_REPO_PATTERN_DETECTED]: CrossRepoPatternDetectedProps;\n\t[AnalyticsEvents.REPO_PERSONALITY_UPDATED]: RepoPersonalityUpdatedProps;\n\t[AnalyticsEvents.GLOBAL_INSIGHT_APPLIED]: GlobalInsightAppliedProps;\n\n\t// Intelligence Layer: GitHub Integration\n\t[AnalyticsEvents.GITHUB_REPO_CONNECTED]: GithubRepoConnectedProps;\n\t[AnalyticsEvents.GITHUB_PR_ANALYZED]: GithubPrAnalyzedProps;\n\t[AnalyticsEvents.GITHUB_COMMIT_SCANNED]: GithubCommitScannedProps;\n\t[AnalyticsEvents.GITHUB_AI_CONTRIBUTION_DETECTED]: GithubAiContributionDetectedProps;\n\t[AnalyticsEvents.GITHUB_CHECK_POSTED]: GithubCheckPostedProps;\n\n\t// Intelligence Layer: MCP Tools\n\t[AnalyticsEvents.MCP_TOOL_CALLED]: McpToolCalledProps;\n\t[AnalyticsEvents.MCP_CONTEXT_PROVIDED]: McpContextProvidedProps;\n\t[AnalyticsEvents.MCP_AGENT_SELF_CHECK]: McpAgentSelfCheckProps;\n\n\t// Intelligence Layer: Community & Engagement\n\t[AnalyticsEvents.DISASTER_STORY_SHARED]: DisasterStorySharedProps;\n\t[AnalyticsEvents.FEEDBACK_SUBMITTED]: FeedbackSubmittedProps;\n\t[AnalyticsEvents.COMMUNITY_ACTION_COMPLETED]: CommunityActionCompletedProps;\n\t[AnalyticsEvents.BETA_ELIGIBILITY_CALCULATED]: BetaEligibilityCalculatedProps;\n\t[AnalyticsEvents.REFERRAL_LINK_GENERATED]: ReferralLinkGeneratedProps;\n\t[AnalyticsEvents.REFERRAL_CONVERTED]: ReferralConvertedProps;\n\n\t// Activation Funnel\n\t[AnalyticsEvents.AUTH_COMPLETED]: AuthCompletedProps;\n\t[AnalyticsEvents.FIRST_SNAPSHOT_CREATED]: FirstSnapshotCreatedProps;\n}\n","/**\n * Neon Documentation Intelligence Infrastructure\n *\n * Provides Neon database client, schema migrations, and types\n * for the documentation knowledgebase (per knowledgebase_1.md).\n *\n * @module infrastructure/neon\n */\n\nexport { type DocEmbedding, type NeonClientConfig, NeonDocClient, type SearchResult } from \"./client\";\nexport { runMigration, verifySchema } from \"./migrations\";\n","/**\n * Neon Database Client for Documentation Intelligence\n *\n * Wrapper around @neondatabase/serverless for the doc embeddings knowledgebase.\n * Provides connection pooling, query helpers, and type-safe interfaces.\n *\n * @module infrastructure/neon/client\n */\n\nimport { type NeonQueryFunction, neon, neonConfig } from \"@neondatabase/serverless\";\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\n/**\n * Documentation embedding record\n */\nexport interface DocEmbedding {\n\tid: string;\n\tlibrary: string;\n\tversion: string;\n\tdoc_type: \"api_reference\" | \"security_pattern\" | \"best_practice\" | \"deprecation\";\n\tchunk_text: string;\n\tembedding: number[];\n\tmetadata: Record<string, unknown>;\n\tsource_url: string | null;\n\tindexed_at: Date;\n}\n\n/**\n * Hybrid search result with similarity score\n */\nexport interface SearchResult {\n\tid: string;\n\tlibrary: string;\n\tversion: string;\n\tdoc_type: string;\n\tchunk_text: string;\n\tmetadata: Record<string, unknown>;\n\tsource_url: string | null;\n\tsimilarity: number;\n}\n\n/**\n * Neon client configuration\n */\nexport interface NeonClientConfig {\n\t/** Neon connection string (pooled URL recommended for queries) */\n\tconnectionString: string;\n\t/** Enable connection caching (default: true) */\n\tenableCache?: boolean;\n}\n\n// ============================================================================\n// CLIENT\n// ============================================================================\n\n/**\n * Neon documentation intelligence client\n *\n * @example\n * ```typescript\n * const client = new NeonDocClient({\n * connectionString: process.env.NEON_DATABASE_URL!\n * });\n *\n * const results = await client.hybridSearch(\n * embedding,\n * { library: 'react', version: '18.x', limit: 5 }\n * );\n * ```\n */\nexport class NeonDocClient {\n\tprivate sql: NeonQueryFunction<false, false>;\n\n\tconstructor(config: NeonClientConfig) {\n\t\t// Enable connection caching (Neon handles pooling transparently)\n\t\tif (config.enableCache !== false) {\n\t\t\tneonConfig.fetchConnectionCache = true;\n\t\t}\n\n\t\t// Create query function\n\t\tthis.sql = neon(config.connectionString);\n\t}\n\n\t/**\n\t * Execute hybrid search against doc_embeddings\n\t *\n\t * @param queryEmbedding - 768-dim vector from text-embedding-3-small\n\t * @param options - Search filters and limits\n\t * @returns Ranked search results with similarity scores\n\t */\n\tasync hybridSearch(\n\t\tqueryEmbedding: number[],\n\t\toptions: {\n\t\t\tlibrary?: string;\n\t\t\tversion?: string;\n\t\t\tlimit?: number;\n\t\t\tsimilarityThreshold?: number;\n\t\t} = {},\n\t): Promise<SearchResult[]> {\n\t\tif (queryEmbedding.length !== 768) {\n\t\t\tthrow new Error(`Expected 768-dim embedding, got ${queryEmbedding.length}`);\n\t\t}\n\n\t\tconst { library = null, version = null, limit = 5, similarityThreshold = 0.75 } = options;\n\n\t\t// Convert embedding to pgvector format\n\t\tconst embeddingStr = `[${queryEmbedding.join(\",\")}]`;\n\n\t\tconst results = await this.sql`\n SELECT * FROM hybrid_search(\n ${embeddingStr}::vector(768),\n ${library},\n ${version},\n ${limit},\n ${similarityThreshold}\n )\n `;\n\n\t\treturn results as SearchResult[];\n\t}\n\n\t/**\n\t * Insert a single doc embedding\n\t *\n\t * @param doc - Document embedding record\n\t * @returns Inserted record ID\n\t */\n\tasync insertDoc(doc: Omit<DocEmbedding, \"id\" | \"indexed_at\">): Promise<string> {\n\t\tif (doc.embedding.length !== 768) {\n\t\t\tthrow new Error(`Expected 768-dim embedding, got ${doc.embedding.length}`);\n\t\t}\n\n\t\tconst embeddingStr = `[${doc.embedding.join(\",\")}]`;\n\n\t\tconst result = await this.sql`\n INSERT INTO doc_embeddings (library, version, doc_type, chunk_text, embedding, metadata, source_url)\n VALUES (\n ${doc.library},\n ${doc.version},\n ${doc.doc_type},\n ${doc.chunk_text},\n ${embeddingStr}::vector(768),\n ${JSON.stringify(doc.metadata)},\n ${doc.source_url}\n )\n ON CONFLICT (library, version, chunk_text)\n DO UPDATE SET\n embedding = EXCLUDED.embedding,\n metadata = EXCLUDED.metadata,\n indexed_at = NOW()\n RETURNING id\n `;\n\n\t\treturn result[0]?.id ?? \"\";\n\t}\n\n\t/**\n\t * Batch insert doc embeddings (optimized for bulk ingestion)\n\t *\n\t * @param docs - Array of document embeddings\n\t * @returns Count of inserted/updated records\n\t */\n\tasync batchInsertDocs(docs: Array<Omit<DocEmbedding, \"id\" | \"indexed_at\">>): Promise<number> {\n\t\tif (docs.length === 0) {\n\t\t\treturn 0;\n\t\t}\n\n\t\t// Validate all embeddings are 768-dim\n\t\tfor (const doc of docs) {\n\t\t\tif (doc.embedding.length !== 768) {\n\t\t\t\tthrow new Error(`Expected 768-dim embedding, got ${doc.embedding.length}`);\n\t\t\t}\n\t\t}\n\n\t\t// Insert docs one by one (batch optimization can be added later with proper parameterization)\n\t\tlet count = 0;\n\t\tfor (const doc of docs) {\n\t\t\tawait this.insertDoc(doc);\n\t\t\tcount++;\n\t\t}\n\n\t\treturn count;\n\t}\n\n\t/**\n\t * Get embedding stats (total chunks, by library, etc.)\n\t */\n\tasync getStats(): Promise<{\n\t\ttotal: number;\n\t\tbyLibrary: Record<string, number>;\n\t\tbyDocType: Record<string, number>;\n\t}> {\n\t\tconst totalResult = await this.sql`SELECT COUNT(*) as count FROM doc_embeddings`;\n\t\tconst total = Number(totalResult[0]?.count ?? 0);\n\n\t\tconst byLibraryResult = await this.sql`\n SELECT library, COUNT(*) as count \n FROM doc_embeddings \n GROUP BY library\n `;\n\n\t\tconst byDocTypeResult = await this.sql`\n SELECT doc_type, COUNT(*) as count \n FROM doc_embeddings \n GROUP BY doc_type\n `;\n\n\t\treturn {\n\t\t\ttotal,\n\t\t\tbyLibrary: Object.fromEntries(byLibraryResult.map((r) => [r.library, Number(r.count)])),\n\t\t\tbyDocType: Object.fromEntries(byDocTypeResult.map((r) => [r.doc_type, Number(r.count)])),\n\t\t};\n\t}\n}\n","/**\n * Neon Schema Migrations\n *\n * Helper to run the doc_embeddings schema migration on Neon.\n * Reads schema.sql and executes it via @neondatabase/serverless.\n *\n * @module infrastructure/neon/migrations\n */\n\nimport { readFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { type NeonQueryFunction, neon } from \"@neondatabase/serverless\";\n\n// Edge Runtime compatible: convert import.meta.url string to path\n// Using dirname() is required for Edge Runtime compatibility\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Run the documentation intelligence schema migration\n *\n * @param connectionString - Neon connection string (use direct URL for migrations, not pooled)\n * @returns Migration result\n *\n * @example\n * ```typescript\n * await runMigration(process.env.NEON_DIRECT_URL!);\n * ```\n */\nexport async function runMigration(connectionString: string): Promise<{\n\tsuccess: boolean;\n\terror?: string;\n}> {\n\ttry {\n\t\tconst sql: NeonQueryFunction<false, false> = neon(connectionString);\n\n\t\t// Read schema.sql\n\t\tconst schemaPath = join(__dirname, \"schema.sql\");\n\t\tconst schemaSql = readFileSync(schemaPath, \"utf-8\");\n\n\t\t// Execute migration (Neon supports multistatement SQL)\n\t\tawait sql(schemaSql);\n\n\t\treturn { success: true };\n\t} catch (error) {\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t};\n\t}\n}\n\n/**\n * Verify schema is correctly installed\n *\n * @param connectionString - Neon connection string\n * @returns Verification result with details\n */\nexport async function verifySchema(connectionString: string): Promise<{\n\tvalid: boolean;\n\tchecks: {\n\t\ttableExists: boolean;\n\t\thnswIndexExists: boolean;\n\t\thybridSearchFunctionExists: boolean;\n\t};\n\terror?: string;\n}> {\n\ttry {\n\t\tconst sql: NeonQueryFunction<false, false> = neon(connectionString);\n\n\t\t// Check if table exists\n\t\tconst tableCheck = await sql`\n SELECT EXISTS (\n SELECT FROM information_schema.tables \n WHERE table_name = 'doc_embeddings'\n ) as exists\n `;\n\t\tconst tableExists = tableCheck[0]?.exists === true;\n\n\t\t// Check if HNSW index exists\n\t\tconst indexCheck = await sql`\n SELECT EXISTS (\n SELECT FROM pg_indexes \n WHERE indexname = 'doc_embeddings_hnsw_idx'\n ) as exists\n `;\n\t\tconst hnswIndexExists = indexCheck[0]?.exists === true;\n\n\t\t// Check if hybrid_search function exists\n\t\tconst functionCheck = await sql`\n SELECT EXISTS (\n SELECT FROM pg_proc \n WHERE proname = 'hybrid_search'\n ) as exists\n `;\n\t\tconst hybridSearchFunctionExists = functionCheck[0]?.exists === true;\n\n\t\tconst valid = tableExists && hnswIndexExists && hybridSearchFunctionExists;\n\n\t\treturn {\n\t\t\tvalid,\n\t\t\tchecks: {\n\t\t\t\ttableExists,\n\t\t\t\thnswIndexExists,\n\t\t\t\thybridSearchFunctionExists,\n\t\t\t},\n\t\t};\n\t} catch (error) {\n\t\treturn {\n\t\t\tvalid: false,\n\t\t\tchecks: {\n\t\t\t\ttableExists: false,\n\t\t\t\thnswIndexExists: false,\n\t\t\t\thybridSearchFunctionExists: false,\n\t\t\t},\n\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t};\n\t}\n}\n","/**\n * vocabulary.ts - Canonical Agent Action Vocabulary\n *\n * OBS-VOCAB-01: Defines the typed enum for all swarm-instrumented operations.\n * Every span emitted by a Vreko swarm agent MUST use a value from this enum.\n *\n * Adding a new verb requires:\n * 1. Add to this enum\n * 2. Update meta-canon.md §3.2\n * 3. Update ActionPayload discriminated union in wrapper.ts\n */\n\n// ─── Agent Action Enum ────────────────────────────────────────────────────────\n\nexport enum AgentAction {\n\t// Reads\n\tSEARCH = \"SEARCH\",\n\tREAD_FILE = \"READ_FILE\",\n\tLIST_DIR = \"LIST_DIR\",\n\tGREP = \"GREP\",\n\t// Writes\n\tWRITE_FILE = \"WRITE_FILE\",\n\tEDIT_FILE = \"EDIT_FILE\",\n\tDELETE_FILE = \"DELETE_FILE\",\n\t// Execution\n\tRUN_TEST = \"RUN_TEST\",\n\tRUN_BUILD = \"RUN_BUILD\",\n\tRUN_LINT = \"RUN_LINT\",\n\tRUN_SHELL = \"RUN_SHELL\",\n\t// VCS\n\tCOMMIT = \"COMMIT\",\n\tREVERT = \"REVERT\",\n\tBRANCH = \"BRANCH\",\n\tMERGE = \"MERGE\",\n\t// Network / external\n\tHTTP_GET = \"HTTP_GET\",\n\tHTTP_POST = \"HTTP_POST\",\n\tMCP_CALL = \"MCP_CALL\",\n\t// Reasoning / control\n\tPLAN = \"PLAN\",\n\tREVIEW = \"REVIEW\",\n\tDECIDE = \"DECIDE\",\n\tASK_USER = \"ASK_USER\",\n\t// Verification\n\tVERIFY_GATE = \"VERIFY_GATE\",\n\tSCORE_R = \"SCORE_R\",\n\t// Swarm pipeline events (meta-canon §3.2 additions)\n\tSEARCH_EXTERNAL = \"SEARCH_EXTERNAL\", // external web/GitHub search - only Auditor + Spec Writer\n\tFETCH_DOCS = \"FETCH_DOCS\", // library/API documentation retrieval via MCP\n\tCITE = \"CITE\", // record a citation in external-findings section\n\tGATE_OPEN = \"GATE_OPEN\", // conductor opens a human gate\n\tGATE_CLOSE = \"GATE_CLOSE\", // conductor closes a human gate (Q approval received)\n\tDISPATCH = \"DISPATCH\", // conductor assigns a spec to a worktree\n\tAUDIT_PHASE = \"AUDIT_PHASE\", // auditor runs Phase 1 internal or Phase 2 external audit\n\tSPEC_WRITE = \"SPEC_WRITE\", // spec writer authors a specification\n\t// Pipeline phase boundary events\n\tPHASE_START = \"PHASE_START\", // emitted when a pipeline stage begins\n\tPHASE_END = \"PHASE_END\", // emitted when a pipeline stage completes or fails\n}\n\n// ─── LLM Provider Enum ─────────────────────────────────────────────────────────\n// OBS-PROVIDER-01: Provider and model are mandatory fields on Generation-type observations.\n\nexport enum LLMProvider {\n\tANTHROPIC = \"anthropic\",\n\tOPENAI = \"openai\",\n\tGEMINI = \"gemini\",\n\tOLLAMA = \"ollama\",\n\tMISTRAL = \"mistral\",\n\tCOHERE = \"cohere\",\n\tUNKNOWN = \"unknown\", // escape hatch - logs a warning, never silently accepted\n}\n\n// ─── Agent Role Enum ──────────────────────────────────────────────────────────\n\nexport enum AgentRole {\n\tSPEC_WRITER = \"spec-writer\",\n\tAUDITOR = \"auditor\",\n\tIMPLEMENTER = \"implementer\",\n\tADVERSARIAL_REVIEWER = \"adversarial-reviewer\",\n\tCONDUCTOR = \"conductor\",\n\tDRIFT_DETECTOR = \"drift-detector\",\n\tGATEKEEPER = \"gatekeeper\",\n\tINTEGRATOR = \"integrator\",\n\tRESEARCHER = \"researcher\",\n\tDEVSECOPS = \"devsecops\",\n\tTECHNICAL_WRITER = \"technical-writer\",\n\tRELEASE_MANAGER = \"release-manager\",\n\tMASTER_COORDINATOR = \"master-coordinator\",\n}\n\n// ─── Action Payload Discriminated Union ───────────────────────────────────────\n// OBS-VOCAB-03: TypeScript enforces required fields per action at the call site.\n\nexport type ActionPayload<A extends AgentAction> = A extends AgentAction.SEARCH\n\t? { query: string; scope?: string }\n\t: A extends AgentAction.READ_FILE\n\t\t? { path: string }\n\t\t: A extends AgentAction.LIST_DIR\n\t\t\t? { path: string }\n\t\t\t: A extends AgentAction.GREP\n\t\t\t\t? { pattern: string; path?: string }\n\t\t\t\t: A extends AgentAction.WRITE_FILE\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tpath: string;\n\t\t\t\t\t\t\taffectedPaths: string[]; // all paths written in this action, including path itself\n\t\t\t\t\t\t\tlinesAdded?: number; // optional - populate if available from diff\n\t\t\t\t\t\t\tlinesRemoved?: number;\n\t\t\t\t\t\t}\n\t\t\t\t\t: A extends AgentAction.EDIT_FILE\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\tpath: string;\n\t\t\t\t\t\t\t\taffectedPaths: string[];\n\t\t\t\t\t\t\t\tlinesAdded?: number;\n\t\t\t\t\t\t\t\tlinesRemoved?: number;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: A extends AgentAction.DELETE_FILE\n\t\t\t\t\t\t\t? { path: string }\n\t\t\t\t\t\t\t: A extends AgentAction.RUN_TEST\n\t\t\t\t\t\t\t\t? { command: string; exitCode?: number }\n\t\t\t\t\t\t\t\t: A extends AgentAction.RUN_BUILD\n\t\t\t\t\t\t\t\t\t? { command: string; exitCode?: number }\n\t\t\t\t\t\t\t\t\t: A extends AgentAction.RUN_LINT\n\t\t\t\t\t\t\t\t\t\t? { command: string; exitCode?: number }\n\t\t\t\t\t\t\t\t\t\t: A extends AgentAction.RUN_SHELL\n\t\t\t\t\t\t\t\t\t\t\t? { command: string; exitCode?: number }\n\t\t\t\t\t\t\t\t\t\t\t: A extends AgentAction.COMMIT\n\t\t\t\t\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tsha: string;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tmessage: string;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\taffectedPaths: string[]; // full list of paths in the commit\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tauthorModel: string; // model string, e.g. \"claude-opus-4-6\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tauthorProvider: LLMProvider;\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t: A extends AgentAction.REVERT\n\t\t\t\t\t\t\t\t\t\t\t\t\t? { sha: string; reason?: string }\n\t\t\t\t\t\t\t\t\t\t\t\t\t: A extends AgentAction.BRANCH\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t? { name: string }\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t: A extends AgentAction.MERGE\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t? { sourceBranch: string; targetBranch: string }\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t: A extends AgentAction.HTTP_GET\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t? { url: string; statusCode?: number }\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t: A extends AgentAction.HTTP_POST\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t? { url: string; statusCode?: number }\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t: A extends AgentAction.MCP_CALL\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t? { tool: string; server?: string }\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t: A extends AgentAction.PLAN\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription: string;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tprovider?: string;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tmodel?: string;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tinputTokens?: number;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\toutputTokens?: number;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tcacheWriteTokens?: number;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tcacheReadTokens?: number;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t: A extends AgentAction.REVIEW\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t? { target: string }\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t: A extends AgentAction.DECIDE\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdecision: string;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\trationale?: string;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tstopReason?: string;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tresponseId?: string;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t: A extends AgentAction.ASK_USER\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t? { question: string }\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t: A extends AgentAction.VERIFY_GATE\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tgateId: string;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tpassed: boolean;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t: A extends AgentAction.SCORE_R\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\trId: string;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tpassed: boolean;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t: A extends AgentAction.SEARCH_EXTERNAL\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tquery: string;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsource?:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t| \"web\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t| \"github\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t| \"mcp-docs\";\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t: A extends AgentAction.FETCH_DOCS\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tlibrary: string;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tversion?: string;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\turl?: string;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t: A extends AgentAction.CITE\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tclaim: string;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsource: string;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\texcerpt: string;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdateAccessed: string; // ISO date string\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t: A extends AgentAction.GATE_OPEN\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tgateType:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t| \"human-1\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t| \"human-2\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t| \"human-3\";\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tspecId: string;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t: A extends AgentAction.GATE_CLOSE\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tgateType:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t| \"human-1\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t| \"human-2\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t| \"human-3\";\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tspecId: string;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdurationMs?: number; // milliseconds gate was open\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t: A extends AgentAction.DISPATCH\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tspecId: string;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tworktreePath: string;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tbranch: string;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t: A extends AgentAction.AUDIT_PHASE\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tauditPhase:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t| \"1\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t| \"2\";\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tspecId: string;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t: A extends AgentAction.SPEC_WRITE\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tspecId: string;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tpriority?:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t| \"P0\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t| \"P1\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t| \"P2\";\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t: A extends AgentAction.PHASE_START\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tphase:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t| \"audit\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t| \"spec\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t| \"implement\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t| \"review\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t| \"gate\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t| \"merge\";\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tspecId: string;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tpioneerBlocker?: boolean;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t: A extends AgentAction.PHASE_END\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tphase:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t| \"audit\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t| \"spec\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t| \"implement\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t| \"review\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t| \"gate\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t| \"merge\";\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tspecId: string;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\toutcome:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t| \"completed\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t| \"abandoned\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t| \"failed\";\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tdurationMs?: number;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t: Record<\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tstring,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tunknown\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t>;\n\n// ─── Tool Decision Span Shape ─────────────────────────────────────────────────\n// OBS-DECISION-01: Distinct span type for tool choice recording.\n\nexport interface ToolDecision {\n\t/** Actions the agent could have taken */\n\tavailable: AgentAction[];\n\t/** Actions the agent actually took */\n\tinvoked: AgentAction[];\n\t/** Actions available but skipped - wrapper validates: skipped = available \\ invoked */\n\tskipped: AgentAction[];\n\t/** Why (free text, max 1000 chars) */\n\trationale: string;\n\t/** Identifier for where the decision was made: \"pre-write\", \"pre-commit\", \"audit-completeness\", \"pre-approve\" */\n\tdecisionPoint: string;\n}\n","/**\n * wrapper.ts - Typed Observability Wrapper\n *\n * All swarm agent telemetry routes through this module.\n * Enforces the AgentAction enum at compile time (OBS-VOCAB-04).\n * Validates metadata keys (OBS-VOCAB-05).\n * Routes spans through otel-emit.ts via the Collector path (OBS-BOUNDARY-03).\n *\n * DO NOT call otel-emit.ts directly - use this wrapper.\n * DO NOT add @langfuse/node imports here - Collector-only path is the locked invariant.\n */\n\nimport { randomUUID } from \"node:crypto\";\nimport type { ActionPayload, ToolDecision } from \"./vocabulary.js\";\nimport { AgentAction, type AgentRole } from \"./vocabulary.js\";\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport interface SpanHandle {\n\tspanId: string;\n\ttraceId: string;\n\tend(): void;\n}\n\nexport interface RecordActionOptions {\n\ttraceId: string;\n\tparentSpanId?: string;\n\tagentRole: AgentRole;\n\t/** Transport: always \"collector\" - SDK-direct is a no-op stub for future use (OBS-BOUNDARY-03) */\n\ttransport?: \"collector\" | \"sdk\";\n\t/** Additional metadata. Keys: camelCase /^[a-zA-Z][a-zA-Z0-9]*$/, values ≤200 chars. */\n\tmetadata?: Record<string, string>;\n\t/**\n\t * OBS-VOCAB-02: Spec identifier (e.g. \"META-OBS-01\"). When combined with phaseId,\n\t * used to build the Langfuse trace name: \"{agentRole}:{specId}/{phaseId}\".\n\t */\n\tspecId?: string;\n\t/**\n\t * OBS-VOCAB-02: Phase identifier (e.g. \"phase-1\"). Combined with specId for trace name.\n\t */\n\tphaseId?: string;\n\t/**\n\t * OBS-VOCAB-07: Model identifier for the agent run (e.g. \"claude-sonnet-4-6\").\n\t * Emitted as metadata.model on the span. Defaults to process.env.VREKO_AGENT_MODEL.\n\t */\n\tmodel?: string;\n\t/**\n\t * Langfuse user.id - maps to the developer or workspace that triggered this run.\n\t * Enables per-user views in the Langfuse UI.\n\t */\n\tuserId?: string;\n\t/**\n\t * vreko.workspace.id - workspace-scoped attribution for multi-workspace deployments.\n\t * Compute via generateWorkspaceId() from @vreko/workspace-identity at the call site.\n\t */\n\tworkspaceId?: string;\n\t/**\n\t * deployment.environment - separates prod/dogfood/local traces.\n\t * Falls back to LANGFUSE_TRACING_ENVIRONMENT env var, then \"unknown\".\n\t */\n\tenvironment?: string;\n\t/**\n\t * vreko.prompt.version - prompt template version for Langfuse experiment diffing.\n\t * E.g. \"conductor-v2\", \"spec-writer-v1.1\".\n\t */\n\tpromptVersion?: string;\n}\n\nexport interface RecordDecisionOptions {\n\ttraceId: string;\n\tparentSpanId?: string;\n\tagentRole: AgentRole;\n\ttransport?: \"collector\" | \"sdk\";\n\tmetadata?: Record<string, string>;\n\t/**\n\t * OBS-VOCAB-03: Spec and phase context for trace naming.\n\t * Name formula: \"{agentRole}:{specId}/{phaseId}\" when both present;\n\t * falls back to \"{agentRole}:tool_decision\".\n\t */\n\tspecId?: string;\n\tphaseId?: string;\n}\n\nexport interface RecordGateOptions {\n\ttraceId: string;\n\tspecId?: string;\n\tphaseId?: string;\n\ttransport?: \"collector\" | \"sdk\";\n\t/**\n\t * OBS-VOCAB-03: Optional agent role - used in trace name formula:\n\t * \"{agentRole}:{specId}/{phaseId}\" when all three are set.\n\t * Falls back to \"gate:{specId}/{phaseId}\" or \"verify_gate:{rId}\".\n\t */\n\tagentRole?: AgentRole;\n\t/**\n\t * ISO timestamp of when the gate was opened (for wait duration calculation).\n\t * When provided, emits vreko.gate.openedAt and vreko.gate.waitDurationMs attributes.\n\t */\n\tgateOpenedAt?: string;\n}\n\n// ─── Startup validation ───────────────────────────────────────────────────────\n\n/**\n * LANGFUSE-03: Validate Langfuse env vars at process boot.\n * Call once from every entry point that initializes Langfuse.\n * Throws on misconfiguration - fail fast rather than emitting to a wrong endpoint.\n */\nexport function validateLangfuseConfig(): void {\n\tconst baseUrl = process.env.LANGFUSE_BASE_URL;\n\tconst secretKey = process.env.LANGFUSE_SECRET_KEY;\n\tconst publicKey = process.env.LANGFUSE_PUBLIC_KEY;\n\n\tif (!baseUrl?.startsWith(\"http\")) {\n\t\tthrow new Error(`LANGFUSE_BASE_URL invalid: expected URL, got \"${baseUrl?.slice(0, 20)}...\"`);\n\t}\n\tif (!secretKey?.startsWith(\"sk-lf-\")) {\n\t\tthrow new Error(`LANGFUSE_SECRET_KEY invalid: expected key starting with sk-lf-`);\n\t}\n\tif (!publicKey?.startsWith(\"pk-lf-\")) {\n\t\tthrow new Error(`LANGFUSE_PUBLIC_KEY invalid: expected key starting with pk-lf-`);\n\t}\n}\n\n// ─── Metadata validation ──────────────────────────────────────────────────────\n\nconst METADATA_KEY_RE = /^[a-zA-Z][a-zA-Z0-9]*$/;\nconst METADATA_VALUE_MAX = 200;\n\n/**\n * OBS-VOCAB-05: Validate propagated metadata keys and values.\n * Keys must match /^[a-zA-Z][a-zA-Z0-9]*$/ (camelCase, no hyphens/underscores).\n * Values must be ≤200 chars.\n * Throws on violation - silent dropping is the exact failure mode this spec prevents.\n */\nexport function validateMetadata(metadata: Record<string, string>): void {\n\tfor (const [key, value] of Object.entries(metadata)) {\n\t\tif (!METADATA_KEY_RE.test(key)) {\n\t\t\tthrow new Error(\n\t\t\t\t`[observability] Invalid metadata key \"${key}\": must match /^[a-zA-Z][a-zA-Z0-9]*$/ (camelCase, no hyphens or underscores). Langfuse silently drops non-conforming keys.`,\n\t\t\t);\n\t\t}\n\t\tif (value.length > METADATA_VALUE_MAX) {\n\t\t\tthrow new Error(\n\t\t\t\t`[observability] Metadata value for key \"${key}\" is ${value.length} chars, exceeds ${METADATA_VALUE_MAX} char limit. Langfuse silently drops oversized values.`,\n\t\t\t);\n\t\t}\n\t}\n}\n\n// ─── Trace name builder ───────────────────────────────────────────────────────\n\n/**\n * OBS-VOCAB-02 / OBS-VOCAB-03: Build a readable Langfuse trace name.\n * Formula: \"{role}:{specId}/{phaseId}\" when specId+phaseId are present;\n * falls back to \"{role}:{fallback}\" (e.g. \"{role}:{action}\", \"{role}:tool_decision\").\n */\nfunction buildTraceName(\n\trole: string,\n\tspecId: string | undefined,\n\tphaseId: string | undefined,\n\tfallback: string,\n): string {\n\tif (specId && phaseId) return `${role}:${specId}/${phaseId}`;\n\treturn `${role}:${fallback}`;\n}\n\n// ─── OTLP emission (Collector path) ──────────────────────────────────────────\n\n// Collector-only path: emit to the local/configured OTLP Collector so redaction,\n// batching, and downstream export policy are never bypassed from this wrapper.\n// Resolution order:\n// 1. COLLECTOR_ENDPOINT - explicit override (used by swarm wrapper directly)\n// 2. OTLP_ENDPOINT - legacy alias\n// 3. OTEL_EXPORTER_OTLP_ENDPOINT - standard OTel SDK base URL (no path); append /v1/traces\n// 4. hardcoded default - local Collector on :4318\nconst _otelBase = process.env.OTEL_EXPORTER_OTLP_ENDPOINT;\nconst COLLECTOR_ENDPOINT =\n\tprocess.env.COLLECTOR_ENDPOINT ??\n\tprocess.env.OTLP_ENDPOINT ??\n\t(_otelBase ? `${_otelBase.replace(/\\/+$/, \"\")}/v1/traces` : \"http://localhost:4318/v1/traces\");\nconst NETWORK_TIMEOUT_MS = 500;\n\nfunction nanoNow(): string {\n\treturn String(BigInt(Date.now()) * 1_000_000n);\n}\n\nfunction newSpanId(): string {\n\treturn randomUUID().replace(/-/g, \"\").slice(0, 16);\n}\n\nfunction buildAuthHeader(): string | null {\n\tconst pk = process.env.LANGFUSE_PUBLIC_KEY;\n\tconst sk = process.env.LANGFUSE_SECRET_KEY;\n\tif (pk && sk) {\n\t\treturn `Basic ${Buffer.from(`${pk}:${sk}`).toString(\"base64\")}`;\n\t}\n\treturn null;\n}\n\ninterface OtlpAttribute {\n\tkey: string;\n\tvalue: { stringValue?: string; boolValue?: boolean; intValue?: string };\n}\n\nfunction toAttr(key: string, value: string | boolean | number): OtlpAttribute {\n\tif (typeof value === \"boolean\") return { key, value: { boolValue: value } };\n\tif (typeof value === \"number\") return { key, value: { intValue: String(value) } };\n\treturn { key, value: { stringValue: String(value) } };\n}\n\nasync function emitSpanToCollector(\n\ttraceId: string,\n\tspanId: string,\n\tparentSpanId: string | undefined,\n\tname: string,\n\tattributes: Record<string, string | boolean | number>,\n\tstartNano: string,\n\tendNano?: string,\n): Promise<void> {\n\tconst auth = buildAuthHeader();\n\tif (!auth) return; // credentials not present - no-op in test/CI environments\n\n\tconst attrs: OtlpAttribute[] = Object.entries(attributes).map(([k, v]) => toAttr(k, v));\n\n\tconst span: Record<string, unknown> = {\n\t\ttraceId,\n\t\tspanId,\n\t\tname,\n\t\tkind: 1,\n\t\tstartTimeUnixNano: startNano,\n\t\tendTimeUnixNano: endNano ?? nanoNow(),\n\t\tattributes: attrs,\n\t\tstatus: { code: 0 },\n\t};\n\tif (parentSpanId) span.parentSpanId = parentSpanId;\n\n\tconst payload = {\n\t\tresourceSpans: [\n\t\t\t{\n\t\t\t\tresource: {\n\t\t\t\t\tattributes: [\n\t\t\t\t\t\ttoAttr(\"gen_ai.workflow.name\", \"vreko-swarm\"),\n\t\t\t\t\t\ttoAttr(\"service.name\", \"vreko-observability\"),\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t\tscopeSpans: [\n\t\t\t\t\t{\n\t\t\t\t\t\tscope: { name: \"vreko.swarm.observability\", version: \"1.0.0\" },\n\t\t\t\t\t\tspans: [span],\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t};\n\n\tconst controller = new AbortController();\n\tconst timer = setTimeout(() => controller.abort(), NETWORK_TIMEOUT_MS);\n\ttry {\n\t\tawait fetch(COLLECTOR_ENDPOINT, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\tAuthorization: auth,\n\t\t\t\t\"x-langfuse-ingestion-version\": \"4\",\n\t\t\t},\n\t\t\tbody: JSON.stringify(payload),\n\t\t\tsignal: controller.signal,\n\t\t});\n\t} catch {\n\t\t// Fire-and-forget - telemetry never blocks agent execution\n\t} finally {\n\t\tclearTimeout(timer);\n\t}\n}\n\n// ─── recordAction ─────────────────────────────────────────────────────────────\n\n/**\n * OBS-VOCAB-02: Typed wrapper for emitting agent action spans.\n *\n * The `action` parameter is constrained to the AgentAction enum - TypeScript\n * rejects string literals at the call site (OBS-VOCAB-04).\n *\n * The `payload` parameter is a discriminated union keyed by action type -\n * TypeScript enforces required fields per action (OBS-VOCAB-03).\n *\n * @throws if metadata fails key/value validation (OBS-VOCAB-05)\n */\nexport async function recordAction<A extends AgentAction>(\n\taction: A,\n\tpayload: ActionPayload<A>,\n\toptions: RecordActionOptions,\n): Promise<SpanHandle> {\n\t// OBS-VOCAB-05: validate metadata eagerly - do not silently drop\n\tif (options.metadata) {\n\t\tvalidateMetadata(options.metadata);\n\t}\n\n\tconst spanId = newSpanId();\n\tconst startNano = nanoNow();\n\n\t// OBS-VOCAB-02: build readable trace name - \"{agentRole}:{specId}/{phaseId}\" or \"{agentRole}:{action}\"\n\tconst traceName = buildTraceName(options.agentRole, options.specId, options.phaseId, action);\n\n\t// OBS-VOCAB-07: resolve model - explicit option takes precedence over env var\n\tconst resolvedModel = options.model ?? process.env.VREKO_AGENT_MODEL;\n\n\tconst attributes: Record<string, string | boolean | number> = {\n\t\t\"gen_ai.operation.name\": \"execute_tool\",\n\t\t\"vreko.agent.role\": options.agentRole,\n\t\t\"vreko.action\": action,\n\t\t\"vreko.trace.name\": traceName,\n\t\t\"gen_ai.conversation.id\": options.traceId,\n\t};\n\n\t// OBS-VOCAB-07: emit model as gen_ai.request.model (OTEL semconv - Langfuse shows model names from this attribute)\n\tif (resolvedModel) {\n\t\tattributes[\"gen_ai.request.model\"] = resolvedModel;\n\t}\n\n\t// User + workspace attribution (Langfuse user tracking)\n\tif (options.userId) attributes[\"user.id\"] = options.userId;\n\tif (options.workspaceId) attributes[\"vreko.workspace.id\"] = options.workspaceId;\n\n\t// Environment: explicit option > LANGFUSE_TRACING_ENVIRONMENT env var > \"unknown\"\n\tattributes[\"deployment.environment\"] = options.environment ?? process.env.LANGFUSE_TRACING_ENVIRONMENT ?? \"unknown\";\n\n\t// Prompt version for Langfuse experiment diffing\n\tif (options.promptVersion) attributes[\"vreko.prompt.version\"] = options.promptVersion;\n\n\t// Merge payload fields as attributes (string values only, for OTLP compatibility)\n\tfor (const [k, v] of Object.entries(payload as Record<string, unknown>)) {\n\t\tif (typeof v === \"string\" || typeof v === \"number\" || typeof v === \"boolean\") {\n\t\t\tattributes[`vreko.action.${k}`] = v as string | number | boolean;\n\t\t}\n\t}\n\n\t// Merge additional metadata\n\tif (options.metadata) {\n\t\tfor (const [k, v] of Object.entries(options.metadata)) {\n\t\t\tattributes[`vreko.meta.${k}`] = v;\n\t\t}\n\t}\n\n\t// SDK-direct transport is a no-op stub - Collector path is locked (OBS-BOUNDARY-03).\n\t// Future SDK-direct activation requires an ADR amendment before wiring.\n\tif (options.transport === \"sdk\") {\n\t\t// no-op: SDK-direct path not yet activated. Span is silently dropped.\n\t\treturn {\n\t\t\tspanId,\n\t\t\ttraceId: options.traceId,\n\t\t\tend: () => {},\n\t\t};\n\t}\n\n\t// Collector path (default): emit via Langfuse OTLP endpoint.\n\t// In production, otel-emit.ts hook routes spans through localhost:4318 → OTel Collector → Langfuse.\n\t// This direct emission is the secondary path used for integration testing and programmatic wrappers.\n\tawait emitSpanToCollector(options.traceId, spanId, options.parentSpanId, traceName, attributes, startNano);\n\n\tconst endNano = nanoNow();\n\n\treturn {\n\t\tspanId,\n\t\ttraceId: options.traceId,\n\t\tend: () => {\n\t\t\t// Span end is emitted inline above (fire-and-forget model).\n\t\t\t// This handle is returned for callers that want to attach child spans.\n\t\t},\n\t};\n}\n\n// ─── recordDecision ───────────────────────────────────────────────────────────\n\n/** OBS-DECISION-04: Validate decision set math and rationale length. */\nfunction validateDecision(decision: ToolDecision): void {\n\t// Subset check must run before set math - invalid invoked makes set math nonsensical.\n\tfor (const a of decision.invoked) {\n\t\tif (!decision.available.includes(a)) {\n\t\t\tthrow new Error(\n\t\t\t\t`[observability] recordDecision: invoked action \"${a}\" is not in available set at \"${decision.decisionPoint}\".`,\n\t\t\t);\n\t\t}\n\t}\n\tconst invokedSet = new Set(decision.invoked);\n\tconst expectedSkipped = decision.available.filter((a) => !invokedSet.has(a));\n\tconst exp = [...expectedSkipped].sort().join(\",\");\n\tconst act = [...decision.skipped].sort().join(\",\");\n\tif (exp !== act) {\n\t\tthrow new Error(\n\t\t\t`[observability] recordDecision set math invalid at \"${decision.decisionPoint}\": ` +\n\t\t\t\t`expected skipped=[${exp}] (available\\\\invoked) but got skipped=[${act}]. ` +\n\t\t\t\t`Agent must not misreport available actions.`,\n\t\t);\n\t}\n\tif (decision.rationale.length > 1000) {\n\t\tthrow new Error(\n\t\t\t`[observability] recordDecision rationale at \"${decision.decisionPoint}\" exceeds 1000 char limit.`,\n\t\t);\n\t}\n}\n\n/** Build decision span attributes. */\nfunction buildDecisionAttributes(\n\tdecision: ToolDecision,\n\toptions: RecordDecisionOptions,\n): Record<string, string | boolean | number> {\n\tconst hasSkipped = decision.skipped.length > 0;\n\tconst attrs: Record<string, string | boolean | number> = {\n\t\t\"gen_ai.operation.name\": \"tool_decision\",\n\t\t\"vreko.agent.role\": options.agentRole,\n\t\t\"vreko.decision.point\": decision.decisionPoint,\n\t\t\"vreko.decision.available\": decision.available.join(\",\"),\n\t\t\"vreko.decision.invoked\": decision.invoked.join(\",\"),\n\t\t\"vreko.decision.skipped\": decision.skipped.join(\",\"),\n\t\t\"vreko.decision.rationale\": decision.rationale.slice(0, 1000),\n\t\t\"vreko.decision.hasSkipped\": hasSkipped,\n\t\t\"gen_ai.conversation.id\": options.traceId,\n\t};\n\t// OBS-DECISION-05: auto-apply \"decision:has-skipped\" tag\n\tif (hasSkipped) attrs[\"vreko.tag\"] = \"decision:has-skipped\";\n\tif (options.metadata) {\n\t\tfor (const [k, v] of Object.entries(options.metadata)) attrs[`vreko.meta.${k}`] = v;\n\t}\n\treturn attrs;\n}\n\n/**\n * OBS-DECISION-02: Emit a tool_decision span.\n * Validates set math (OBS-DECISION-04) and auto-tags skipped decisions (OBS-DECISION-05).\n * @throws on set math violation, metadata error, or rationale overflow\n */\nexport async function recordDecision(decision: ToolDecision, options: RecordDecisionOptions): Promise<SpanHandle> {\n\tvalidateDecision(decision);\n\tif (options.metadata) validateMetadata(options.metadata);\n\tif (options.transport === \"sdk\") return { spanId: newSpanId(), traceId: options.traceId, end: () => {} };\n\tconst spanId = newSpanId();\n\t// OBS-VOCAB-03: build readable trace name for dashboard\n\tconst traceName = buildTraceName(options.agentRole, options.specId, options.phaseId, \"tool_decision\");\n\tconst attributes = buildDecisionAttributes(decision, options);\n\tattributes[\"vreko.trace.name\"] = traceName;\n\tawait emitSpanToCollector(options.traceId, spanId, options.parentSpanId, traceName, attributes, nanoNow());\n\treturn { spanId, traceId: options.traceId, end: () => {} };\n}\n\n// ─── recordGate ───────────────────────────────────────────────────────────────\n\n/**\n * OBS-SCORE-02: Emit a gate verification result as a Langfuse Score + span.\n *\n * Every shell-verifiable gate in every spec should call this after running\n * the gate command. Emits a span with score attributes and updates trace\n * metadata with lastGate and gate:passed / gate:failed tag.\n *\n * Score schema matches Langfuse Score API:\n * { name: rId, value: 0|1, dataType: \"BOOLEAN\", comment: output, traceId }\n */\nexport async function recordGate(\n\trId: string,\n\tpassed: boolean,\n\toutput: string,\n\ttraceId: string,\n\toptions?: RecordGateOptions,\n): Promise<void> {\n\tconst spanId = newSpanId();\n\tconst startNano = nanoNow();\n\n\t// OBS-VOCAB-03: build readable trace name - \"{agentRole}:{specId}/{phaseId}\" or \"gate:{specId}/{phaseId}\" or \"verify_gate:{rId}\"\n\tconst roleOrGate = options?.agentRole ?? \"gate\";\n\tconst traceName = buildTraceName(roleOrGate, options?.specId, options?.phaseId, `verify_gate:${rId}`);\n\n\tconst attributes: Record<string, string | boolean | number> = {\n\t\t\"gen_ai.operation.name\": \"verify_gate\",\n\t\t\"vreko.r.id\": rId,\n\t\t\"vreko.gate.passed\": passed,\n\t\t\"vreko.gate.output\": output.slice(0, 500), // truncate long outputs\n\t\t\"vreko.gate.tag\": passed ? \"gate:passed\" : \"gate:failed\",\n\t\t\"vreko.gate.lastGate\": rId,\n\t\t\"vreko.trace.name\": traceName,\n\t\t\"gen_ai.conversation.id\": traceId,\n\t};\n\n\tif (options?.specId) attributes[\"vreko.spec.id\"] = options.specId;\n\tif (options?.phaseId) attributes[\"vreko.phase.name\"] = options.phaseId;\n\n\tif (options?.gateOpenedAt) {\n\t\tattributes[\"vreko.gate.openedAt\"] = options.gateOpenedAt;\n\t\tconst waitMs = Date.now() - new Date(options.gateOpenedAt).getTime();\n\t\tif (!Number.isNaN(waitMs) && waitMs >= 0) {\n\t\t\tattributes[\"vreko.gate.waitDurationMs\"] = waitMs;\n\t\t}\n\t}\n\n\tif (options?.transport === \"sdk\") return;\n\n\tawait emitSpanToCollector(traceId, spanId, undefined, traceName, attributes, startNano);\n}\n\n// ─── emitPhaseEvent ───────────────────────────────────────────────────────────\n\n/**\n * Convenience wrapper for pipeline phase boundary spans.\n * Emits PHASE_START or PHASE_END via recordAction with consistent attribute population.\n * Use this at the start and end of each pipeline stage (audit/spec/implement/review/gate/merge).\n */\nexport async function emitPhaseEvent(\n\tevent: \"start\" | \"end\",\n\tphase: \"audit\" | \"spec\" | \"implement\" | \"review\" | \"gate\" | \"merge\",\n\toptions: {\n\t\ttraceId: string;\n\t\tspecId: string;\n\t\tagentRole: AgentRole;\n\t\toutcome?: \"completed\" | \"abandoned\" | \"failed\"; // required for \"end\" events\n\t\tdurationMs?: number;\n\t\tpioneerBlocker?: boolean;\n\t\tpriority?: \"P0\" | \"P1\" | \"P2\";\n\t\tmodel?: string;\n\t\tuserId?: string;\n\t\tworkspaceId?: string;\n\t},\n): Promise<SpanHandle> {\n\tif (event === \"start\") {\n\t\treturn recordAction(\n\t\t\tAgentAction.PHASE_START,\n\t\t\t{ phase, specId: options.specId, pioneerBlocker: options.pioneerBlocker },\n\t\t\t{\n\t\t\t\ttraceId: options.traceId,\n\t\t\t\tagentRole: options.agentRole,\n\t\t\t\tspecId: options.specId,\n\t\t\t\tphaseId: phase,\n\t\t\t\tmodel: options.model,\n\t\t\t\tuserId: options.userId,\n\t\t\t\tworkspaceId: options.workspaceId,\n\t\t\t\tmetadata: options.priority ? { priority: options.priority } : undefined,\n\t\t\t},\n\t\t);\n\t}\n\treturn recordAction(\n\t\tAgentAction.PHASE_END,\n\t\t{\n\t\t\tphase,\n\t\t\tspecId: options.specId,\n\t\t\toutcome: options.outcome ?? \"completed\",\n\t\t\tdurationMs: options.durationMs,\n\t\t},\n\t\t{\n\t\t\ttraceId: options.traceId,\n\t\t\tagentRole: options.agentRole,\n\t\t\tspecId: options.specId,\n\t\t\tphaseId: phase,\n\t\t\tmodel: options.model,\n\t\t\tuserId: options.userId,\n\t\t\tworkspaceId: options.workspaceId,\n\t\t},\n\t);\n}\n\n// ─── emitRatchetScores ────────────────────────────────────────────────────────\n\n/**\n * Emit ratchet delta counts as Langfuse Scores.\n * Call at merge time with before/after counts for each tracked ratchet.\n * Each ratchet emits one score: value=true (improved or unchanged), value=false (regressed).\n * A lower count is an improvement (e.g. fewer skipped tests = better).\n */\nexport async function emitRatchetScores(\n\tratchets: Record<string, { before: number; after: number }>,\n\ttraceId: string,\n\tspecId: string,\n\toptions?: { agentRole?: AgentRole },\n): Promise<void> {\n\tconst emits = Object.entries(ratchets).map(([name, { before, after }]) => {\n\t\tconst improved = after <= before; // lower count = improved or unchanged\n\t\tconst output = `before=${before} after=${after} delta=${after - before}`;\n\t\treturn recordGate(`ratchet:${name}`, improved, output, traceId, {\n\t\t\ttraceId,\n\t\t\tspecId,\n\t\t\tagentRole: options?.agentRole,\n\t\t});\n\t});\n\tawait Promise.all(emits);\n}\n\n// ─── Re-export vocabulary ─────────────────────────────────────────────────────\n\nexport type { ActionPayload, ToolDecision } from \"./vocabulary.js\";\n// AgentAction and AgentRole are value-imported above and re-exported here\nexport { AgentAction, AgentRole } from \"./vocabulary.js\";\n","/**\n * AgentSession - Provider-agnostic LLM instrumentation wrapper\n *\n * Provides unified observability across multiple LLM providers (Anthropic, OpenAI, Gemini, Ollama, etc.)\n * All agent calls go through this wrapper regardless of which LLM is used, ensuring consistent\n * telemetry attribution in Langfuse with provider and model as mandatory span attributes.\n *\n * Per OBS-PROVIDER-01: provider and model are mandatory fields on every Generation-type observation.\n */\n\nimport { createHash, randomUUID } from \"node:crypto\";\nimport { type ActionPayload, AgentAction, type AgentRole, LLMProvider } from \"./vocabulary.js\";\nimport { recordAction as emitAction, type RecordActionOptions } from \"./wrapper.js\";\n\nexport interface AgentSessionConfig {\n\trole: AgentRole;\n\tprovider: LLMProvider;\n\tmodel: string;\n\tsessionId: string;\n\ttraceId?: string;\n\tspecId?: string;\n}\n\nexport interface Tool {\n\tname: string;\n\tdescription?: string;\n\tparameters?: Record<string, unknown>;\n}\n\nexport interface AgentSessionOptions {\n\ttimeout?: number;\n\tmaxRetries?: number;\n}\n\nexport interface AgentResult {\n\tcontent: string;\n\tusage?: {\n\t\tinputTokens?: number;\n\t\toutputTokens?: number;\n\t\ttotalTokens?: number;\n\t};\n}\n\n/**\n * Unified AgentSession wrapper for multi-LLM observability\n *\n * Wraps any LLM call (Anthropic, OpenAI, Gemini, Ollama, etc.) with consistent\n * telemetry instrumentation. Provider and model are always included as span\n * attributes per OBS-PROVIDER-01.\n *\n * Example usage:\n * ```ts\n * // Conductor using Claude Opus\n * const session = new AgentSession({\n * role: \"conductor\",\n * provider: LLMProvider.ANTHROPIC,\n * model: \"claude-opus-4-6\",\n * sessionId: \"session-123\"\n * });\n *\n * // Auditor using GPT-4o\n * const session = new AgentSession({\n * role: \"auditor\",\n * provider: LLMProvider.OPENAI,\n * model: \"gpt-4o\",\n * sessionId: \"session-123\"\n * });\n *\n * // Local model for grunt work\n * const session = new AgentSession({\n * role: \"auditor\",\n * provider: LLMProvider.OLLAMA,\n * model: \"llama3\",\n * sessionId: \"session-123\"\n * });\n *\n * const result = await session.run(\"Analyze this code\", tools);\n * ```\n */\nexport class AgentSession {\n\tprivate readonly role: AgentRole;\n\tprivate readonly provider: LLMProvider;\n\tprivate readonly model: string;\n\tprivate readonly sessionId: string;\n\tprivate readonly specId: string | undefined;\n\tprivate readonly traceId: string;\n\tprivate readonly options: AgentSessionOptions;\n\n\tconstructor(config: AgentSessionConfig, options: AgentSessionOptions = {}) {\n\t\tthis.role = config.role;\n\t\tthis.provider = config.provider;\n\t\tthis.model = config.model;\n\t\tthis.sessionId = config.sessionId;\n\t\tthis.specId = config.specId;\n\t\tthis.traceId = config.traceId || this.generateTraceId();\n\t\tthis.options = {\n\t\t\ttimeout: options.timeout ?? 30000,\n\t\t\tmaxRetries: options.maxRetries ?? 3,\n\t\t};\n\t}\n\n\t/**\n\t * Generate a consistent trace ID from session ID and role\n\t */\n\tprivate generateTraceId(): string {\n\t\tconst seed = `${this.sessionId}-${this.role}-${Date.now()}`;\n\t\treturn randomUUID().replace(/-/g, \"\");\n\t}\n\n\t/**\n\t * Run an LLM inference with telemetry instrumentation\n\t *\n\t * Records PLAN and DECIDE actions with provider and model attributes.\n\t * Routes to the appropriate SDK based on provider.\n\t */\n\tasync run(prompt: string, options?: { tools?: Tool[]; maxTokens?: number }): Promise<AgentResult> {\n\t\tconst startTime = Date.now();\n\n\t\t// Record PLAN action - hash prompt, never raw content (OBS-PROVIDER-01)\n\t\tawait this.recordAction(AgentAction.PLAN, {\n\t\t\tdescription: `prompt[${this.hash(prompt).slice(0, 8)}]`,\n\t\t\tprovider: this.provider,\n\t\t\tmodel: this.model,\n\t\t});\n\n\t\ttry {\n\t\t\t// Route to the right SDK internally\n\t\t\tconst result = await this.dispatch(prompt, options);\n\n\t\t\t// Record DECIDE action with output hash (OBS-PROVIDER-01)\n\t\t\tawait this.recordAction(AgentAction.DECIDE, {\n\t\t\t\tdecision: `output[${this.hash(result.content).slice(0, 8)}]`,\n\t\t\t});\n\n\t\t\treturn result;\n\t\t} catch (error) {\n\t\t\t// Record error decision (OBS-PROVIDER-01)\n\t\t\tawait this.recordAction(AgentAction.DECIDE, {\n\t\t\t\tdecision: \"error\",\n\t\t\t\trationale: error instanceof Error ? error.message : String(error),\n\t\t\t});\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Dispatch to the appropriate LLM SDK based on provider\n\t */\n\tprivate async dispatch(prompt: string, options?: { tools?: Tool[]; maxTokens?: number }): Promise<AgentResult> {\n\t\tswitch (this.provider) {\n\t\t\tcase LLMProvider.ANTHROPIC:\n\t\t\t\treturn this.runAnthropic(prompt, options);\n\t\t\tcase LLMProvider.OPENAI:\n\t\t\t\treturn this.runOpenAI(prompt, options);\n\t\t\tcase LLMProvider.GEMINI:\n\t\t\t\treturn this.runGemini(prompt, options);\n\t\t\tcase LLMProvider.OLLAMA:\n\t\t\t\treturn this.runOllama(prompt, options);\n\t\t\tdefault:\n\t\t\t\t// Unknown provider: use Anthropic as fallback for provenance\n\t\t\t\treturn this.runAnthropic(prompt, options);\n\t\t}\n\t}\n\n\t/**\n\t * Anthropic SDK integration\n\t * TODO: Implement with @anthropic-ai/sdk\n\t */\n\tprivate async runAnthropic(prompt: string, options?: { tools?: Tool[]; maxTokens?: number }): Promise<AgentResult> {\n\t\tthrow new Error(\"Anthropic SDK integration not yet implemented\");\n\t}\n\n\t/**\n\t * OpenAI SDK integration\n\t * TODO: Implement with openai package\n\t */\n\tprivate async runOpenAI(prompt: string, options?: { tools?: Tool[]; maxTokens?: number }): Promise<AgentResult> {\n\t\tthrow new Error(\"OpenAI SDK integration not yet implemented\");\n\t}\n\n\t/**\n\t * Google Gemini SDK integration\n\t * TODO: Implement with @google/generative-ai\n\t */\n\tprivate async runGemini(prompt: string, options?: { tools?: Tool[]; maxTokens?: number }): Promise<AgentResult> {\n\t\tthrow new Error(\"Gemini SDK integration not yet implemented\");\n\t}\n\n\t/**\n\t * Ollama (local model) integration\n\t * TODO: Implement with ollama package or HTTP API\n\t */\n\tprivate async runOllama(prompt: string, options?: { tools?: Tool[]; maxTokens?: number }): Promise<AgentResult> {\n\t\tthrow new Error(\"Ollama integration not yet implemented\");\n\t}\n\n\tprivate async recordAction(\n\t\taction: AgentAction,\n\t\tpayload: ActionPayload<typeof action>,\n\t\topts?: Partial<RecordActionOptions>,\n\t): Promise<void> {\n\t\tawait emitAction(action, payload as never, {\n\t\t\ttraceId: this.traceId,\n\t\t\tagentRole: this.role,\n\t\t\tspecId: this.specId,\n\t\t\tmodel: this.model,\n\t\t\t...opts,\n\t\t});\n\t}\n\n\t/**\n\t * Hash sensitive content (prompts, outputs) before recording\n\t * Uses SHA-256 for cryptographic hashing\n\t */\n\tprivate hash(content: string): string {\n\t\treturn createHash(\"sha256\").update(content).digest(\"hex\");\n\t}\n\n\t/**\n\t * Get the trace ID for this session\n\t */\n\tgetTraceId(): string {\n\t\treturn this.traceId;\n\t}\n\n\t/**\n\t * Get the session ID\n\t */\n\tgetSessionId(): string {\n\t\treturn this.sessionId;\n\t}\n\n\t/**\n\t * Get provider and model for observability\n\t */\n\tgetProviderInfo(): { provider: LLMProvider; model: string } {\n\t\treturn { provider: this.provider, model: this.model };\n\t}\n}\n","/**\n * retro-queries.ts - Retrospective Query Helpers\n *\n * OBS-SCORE-04: Provides programmatic access to Langfuse gate scores and\n * decision spans for the retrospective prompt (canon §5.1).\n *\n * These helpers query the Langfuse API directly. They are the primary input\n * for retrospective analysis - transcript grep is the fallback, not primary.\n *\n * Requires LANGFUSE_PUBLIC_KEY, LANGFUSE_SECRET_KEY, LANGFUSE_BASE_URL.\n */\n\nimport { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { AgentRole, LLMProvider, type ToolDecision } from \"./vocabulary.js\";\n\nconst execFileAsync = promisify(execFile);\n\n// ─── Langfuse API client (minimal) ───────────────────────────────────────────\n\nconst NETWORK_TIMEOUT_MS = 5000;\n\nasync function langfuseGet<T>(path: string): Promise<T> {\n\tconst baseUrl = process.env.LANGFUSE_BASE_URL;\n\tconst pk = process.env.LANGFUSE_PUBLIC_KEY;\n\tconst sk = process.env.LANGFUSE_SECRET_KEY;\n\n\tif (!baseUrl?.startsWith(\"http\")) {\n\t\tthrow new Error(`LANGFUSE_BASE_URL invalid: expected URL, got \"${baseUrl?.slice(0, 20)}...\"`);\n\t}\n\tif (!sk?.startsWith(\"sk-lf-\")) {\n\t\tthrow new Error(`LANGFUSE_SECRET_KEY invalid: expected key starting with sk-lf-`);\n\t}\n\tif (!pk?.startsWith(\"pk-lf-\")) {\n\t\tthrow new Error(`LANGFUSE_PUBLIC_KEY invalid: expected key starting with pk-lf-`);\n\t}\n\n\tconst auth = `Basic ${Buffer.from(`${pk}:${sk}`).toString(\"base64\")}`;\n\tconst controller = new AbortController();\n\tconst timer = setTimeout(() => controller.abort(), NETWORK_TIMEOUT_MS);\n\ttry {\n\t\tconst res = await fetch(`${baseUrl}${path}`, {\n\t\t\theaders: { Authorization: auth },\n\t\t\tsignal: controller.signal,\n\t\t});\n\t\tif (!res.ok) {\n\t\t\tthrow new Error(`Langfuse API error: ${res.status} ${res.statusText}`);\n\t\t}\n\t\treturn res.json() as Promise<T>;\n\t} finally {\n\t\tclearTimeout(timer);\n\t}\n}\n\n// ─── Return types ─────────────────────────────────────────────────────────────\n\nexport interface FailedGateSummary {\n\trId: string;\n\tcount: number;\n\tlastFailedAt: string;\n}\n\n// ─── Queries ──────────────────────────────────────────────────────────────────\n\n/**\n * OBS-SCORE-04: Returns gates that have failed in the last N runs.\n * Queries Langfuse Scores API, filters for gate scores with value=0.\n */\nexport async function failedGatesInLastNRuns(n: number): Promise<FailedGateSummary[]> {\n\t// Langfuse Scores API: GET /api/public/scores\n\t// Filter by dataType=BOOLEAN and value=0 (failed gates)\n\tinterface ScoreItem {\n\t\tname: string;\n\t\tvalue: number;\n\t\tcreatedAt: string;\n\t}\n\tinterface ScoreResponse {\n\t\tdata: ScoreItem[];\n\t}\n\tconst response = await langfuseGet<ScoreResponse>(`/api/public/scores?dataType=BOOLEAN&value=0&limit=${n * 10}`);\n\n\t// Aggregate by gate name (rId)\n\tconst map = new Map<string, { count: number; lastFailedAt: string }>();\n\tfor (const score of response.data ?? []) {\n\t\tif (!score.name) continue;\n\t\tconst existing = map.get(score.name);\n\t\tif (existing) {\n\t\t\texisting.count++;\n\t\t\tif (score.createdAt > existing.lastFailedAt) {\n\t\t\t\texisting.lastFailedAt = score.createdAt;\n\t\t\t}\n\t\t} else {\n\t\t\tmap.set(score.name, { count: 1, lastFailedAt: score.createdAt });\n\t\t}\n\t}\n\n\treturn Array.from(map.entries())\n\t\t.map(([rId, { count, lastFailedAt }]) => ({ rId, count, lastFailedAt }))\n\t\t.sort((a, b) => b.count - a.count)\n\t\t.slice(0, n);\n}\n\n/**\n * OBS-SCORE-04: Returns gate IDs that failed on first attempt for a given spec.\n * Finds all gate spans with vreko.spec.id = specId and value=0 on first occurrence.\n */\nexport async function gatesFailingFirstAttempt(specId: string): Promise<string[]> {\n\tinterface ScoreMetadata {\n\t\tspecId?: string;\n\t\t\"vreko.spec.id\"?: string;\n\t}\n\tinterface ScoreItem {\n\t\tname: string;\n\t\tvalue: number;\n\t\tcreatedAt: string;\n\t\tmetadata?: ScoreMetadata;\n\t}\n\tinterface ScoreResponse {\n\t\tdata: ScoreItem[];\n\t}\n\tconst response = await langfuseGet<ScoreResponse>(`/api/public/scores?dataType=BOOLEAN&limit=200`);\n\n\tconst getScoreSpecId = (score: ScoreItem): string | undefined =>\n\t\tscore.metadata?.[\"vreko.spec.id\"] ?? score.metadata?.specId;\n\n\tconst firstAttemptMap = new Map<string, boolean>();\n\t// Sort ascending by createdAt so first entry is the first attempt\n\tconst sorted = [...(response.data ?? [])].sort((a, b) => a.createdAt.localeCompare(b.createdAt));\n\n\tfor (const score of sorted) {\n\t\tif (!score.name) continue;\n\t\tif (getScoreSpecId(score) !== specId) continue;\n\t\tif (!firstAttemptMap.has(score.name)) {\n\t\t\tfirstAttemptMap.set(score.name, score.value === 0);\n\t\t}\n\t}\n\n\treturn Array.from(firstAttemptMap.entries())\n\t\t.filter(([, failedFirst]) => failedFirst)\n\t\t.map(([rId]) => rId);\n}\n\n/**\n * OBS-SCORE-04: Returns tool_decision spans where skipped.length > 0\n * for a given role since a given date.\n */\nexport async function decisionsWithSkips(role: AgentRole, since: Date): Promise<ToolDecision[]> {\n\t// Langfuse Observations API: GET /api/public/observations\n\t// Filter by name=tool_decision and since date\n\tinterface Observation {\n\t\tinput?: Record<string, unknown>;\n\t\tstartTime?: string;\n\t\tmetadata?: Record<string, string>;\n\t}\n\tinterface ObservationResponse {\n\t\tdata: Observation[];\n\t}\n\n\tconst sinceStr = since.toISOString();\n\tconst response = await langfuseGet<ObservationResponse>(\n\t\t`/api/public/observations?name=tool_decision&fromStartTime=${sinceStr}&limit=200`,\n\t);\n\n\tconst results: ToolDecision[] = [];\n\tfor (const obs of response.data ?? []) {\n\t\tconst input = obs.input as Record<string, unknown> | undefined;\n\t\tif (!input) continue;\n\n\t\t// Reconstruct ToolDecision from span attributes\n\t\tconst agentRole = String(input[\"vreko.agent.role\"] ?? \"\");\n\t\tif (agentRole !== role) continue;\n\n\t\tconst skippedStr = String(input[\"vreko.decision.skipped\"] ?? \"\");\n\t\tif (!skippedStr) continue;\n\n\t\tresults.push({\n\t\t\tavailable: String(input[\"vreko.decision.available\"] ?? \"\")\n\t\t\t\t.split(\",\")\n\t\t\t\t.filter(Boolean) as import(\"./vocabulary.js\").AgentAction[],\n\t\t\tinvoked: String(input[\"vreko.decision.invoked\"] ?? \"\")\n\t\t\t\t.split(\",\")\n\t\t\t\t.filter(Boolean) as import(\"./vocabulary.js\").AgentAction[],\n\t\t\tskipped: skippedStr.split(\",\").filter(Boolean) as import(\"./vocabulary.js\").AgentAction[],\n\t\t\trationale: String(input[\"vreko.decision.rationale\"] ?? \"\"),\n\t\t\tdecisionPoint: String(input[\"vreko.decision.point\"] ?? \"\"),\n\t\t});\n\t}\n\n\treturn results;\n}\n\n// ─── Langfuse Trace Lookup (OBS-ATTR-02) ─────────────────────────────────────────\n\ninterface LangfuseTrace {\n\tid: string;\n\tname?: string;\n\ttimestamp?: string;\n\tmetadata?: Record<string, unknown>;\n\tinput?: unknown;\n\toutput?: unknown;\n\ttags?: string[];\n}\n\ninterface TraceListResponse {\n\tdata?: LangfuseTrace[];\n}\n\n/**\n * Look up a Langfuse trace by the git HEAD SHA at session end.\n * otel-emit.ts emits vreko.git.sha.end = HEAD at Stop event. Metadata is\n * stored on the root span (the Langfuse trace). We query a 1-hour window\n * around commitTime and filter client-side for the sha to avoid relying on\n * Langfuse's attribute-filter query syntax, which varies by version.\n */\nasync function lookupTraceByGitSha(sha: string, commitTime: Date): Promise<LangfuseTrace | undefined> {\n\tconst windowMs = 60 * 60 * 1000; // ±1 hour\n\tconst from = new Date(commitTime.getTime() - windowMs).toISOString();\n\tconst to = new Date(commitTime.getTime() + windowMs).toISOString();\n\ttry {\n\t\tconst response = await langfuseGet<TraceListResponse>(\n\t\t\t`/api/public/traces?fromTimestamp=${encodeURIComponent(from)}&toTimestamp=${encodeURIComponent(to)}&limit=100`,\n\t\t);\n\t\treturn response.data?.find((t) => t.metadata?.[\"vreko.git.sha.end\"] === sha);\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n// ─── Attribution Chain Queries (OBS-ATTR-02) ─────────────────────────────────────\n\nexport interface AttributionLink {\n\tcommitSha: string;\n\tcommittedAt: Date;\n\tauthorModel: string;\n\tauthorProvider: LLMProvider;\n\tagentRole: AgentRole;\n\ttraceId: string;\n\tspecId?: string;\n\tlinesAdded?: number;\n\tlinesRemoved?: number;\n}\n\nexport interface AttributionChain {\n\tfilePath: string;\n\tlinks: AttributionLink[]; // chronological, oldest first\n\tmodelSummary: Record<string, number>; // model → commit count\n\tproviderSummary: Record<string, number>;\n\thumanCommits: number; // commits with no traceId (human-authored)\n\tcoverage: number; // 0–1, fraction of commits with provenance\n}\n\n/**\n * OBS-ATTR-02: Returns attribution chain for a given file.\n * Walks git log for filePath and queries Langfuse traces for each commit.\n */\nexport async function attributionChain(\n\tfilePath: string,\n\toptions?: {\n\t\tsince?: Date;\n\t\tlimit?: number;\n\t\tincludeHuman?: boolean;\n\t},\n): Promise<AttributionChain> {\n\tconst limit = options?.limit ?? 50;\n\n\tconst gitArgs = [\n\t\t\"log\",\n\t\t\"--follow\",\n\t\t\"--pretty=format:%H|%ae|%ad|%s\",\n\t\t\"--date=iso\",\n\t\t\"-n\",\n\t\tString(limit),\n\t\t\"--\",\n\t\tfilePath, // passed as separate arg - no shell injection\n\t];\n\n\tif (options?.since) {\n\t\tgitArgs.splice(gitArgs.indexOf(\"--\"), 0, \"--after=\" + options.since.toISOString());\n\t}\n\n\tlet stdout: string;\n\ttry {\n\t\tconst result = await execFileAsync(\"git\", gitArgs, { encoding: \"utf-8\" });\n\t\tstdout = result.stdout;\n\t} catch {\n\t\treturn {\n\t\t\tfilePath,\n\t\t\tlinks: [],\n\t\t\tmodelSummary: {},\n\t\t\tproviderSummary: {},\n\t\t\thumanCommits: 0,\n\t\t\tcoverage: 0,\n\t\t};\n\t}\n\n\tconst lines = stdout.trim().split(\"\\n\").filter(Boolean);\n\tconst links: AttributionLink[] = [];\n\tlet humanCommits = 0;\n\n\tfor (const line of lines) {\n\t\tconst pipeIdx1 = line.indexOf(\"|\");\n\t\tconst pipeIdx2 = line.indexOf(\"|\", pipeIdx1 + 1);\n\t\tconst pipeIdx3 = line.indexOf(\"|\", pipeIdx2 + 1);\n\t\tif (pipeIdx1 === -1 || pipeIdx2 === -1 || pipeIdx3 === -1) continue;\n\n\t\tconst sha = line.slice(0, pipeIdx1).trim();\n\t\tconst email = line.slice(pipeIdx1 + 1, pipeIdx2).trim();\n\t\tconst dateStr = line.slice(pipeIdx2 + 1, pipeIdx3).trim();\n\t\tconst subject = line.slice(pipeIdx3 + 1).trim();\n\n\t\tif (!sha || !email) continue;\n\n\t\tconst committedAt = new Date(dateStr);\n\t\tif (Number.isNaN(committedAt.getTime())) continue;\n\n\t\t// Heuristic: treat conventional-commit subjects as agent-authored\n\t\t// until Langfuse trace lookup is implemented.\n\t\tconst isConventionalCommit = /^(fix|feat|chore|refactor|test|docs|style|perf)\\(/.test(subject);\n\n\t\tif (!isConventionalCommit) {\n\t\t\thumanCommits++;\n\t\t\tif (options?.includeHuman === false) continue;\n\t\t}\n\n\t\t// OBS-ATTR-02: Query Langfuse by vreko.git.sha.end = sha.\n\t\t// otel-emit.ts sets this attribute on the root span at Stop time.\n\t\tconst trace = await lookupTraceByGitSha(sha, committedAt);\n\t\tconst traceMetadata = trace?.metadata ?? {};\n\t\tconst authorModel =\n\t\t\ttypeof traceMetadata[\"gen_ai.request.model\"] === \"string\"\n\t\t\t\t? traceMetadata[\"gen_ai.request.model\"]\n\t\t\t\t: \"unknown\";\n\t\tconst rawProvider =\n\t\t\ttypeof traceMetadata[\"gen_ai.provider.name\"] === \"string\"\n\t\t\t\t? traceMetadata[\"gen_ai.provider.name\"]\n\t\t\t\t: undefined;\n\t\tconst authorProvider = (Object.values(LLMProvider) as string[]).includes(rawProvider ?? \"\")\n\t\t\t? (rawProvider as LLMProvider)\n\t\t\t: LLMProvider.UNKNOWN;\n\t\tconst rawRole =\n\t\t\ttypeof traceMetadata[\"gen_ai.agent.role\"] === \"string\" ? traceMetadata[\"gen_ai.agent.role\"] : undefined;\n\t\tconst agentRole = (Object.values(AgentRole) as string[]).includes(rawRole ?? \"\")\n\t\t\t? (rawRole as AgentRole)\n\t\t\t: AgentRole.IMPLEMENTER;\n\t\tconst specId = typeof traceMetadata[\"vreko.spec.id\"] === \"string\" ? traceMetadata[\"vreko.spec.id\"] : undefined;\n\n\t\tlinks.push({\n\t\t\tcommitSha: sha,\n\t\t\tcommittedAt,\n\t\t\tauthorModel,\n\t\t\tauthorProvider,\n\t\t\tagentRole,\n\t\t\ttraceId: trace?.id ?? \"\",\n\t\t\tspecId,\n\t\t\tlinesAdded: undefined,\n\t\t\tlinesRemoved: undefined,\n\t\t});\n\t}\n\n\tconst totalCommits = lines.length;\n\tconst tracedLinks = links.filter((l) => l.traceId);\n\tconst coverage = totalCommits > 0 ? tracedLinks.length / totalCommits : 0;\n\n\tconst modelSummary: Record<string, number> = {};\n\tconst providerSummary: Record<string, number> = {};\n\tfor (const link of tracedLinks) {\n\t\tmodelSummary[link.authorModel] = (modelSummary[link.authorModel] ?? 0) + 1;\n\t\tproviderSummary[link.authorProvider] = (providerSummary[link.authorProvider] ?? 0) + 1;\n\t}\n\n\treturn {\n\t\tfilePath,\n\t\tlinks,\n\t\tmodelSummary,\n\t\tproviderSummary,\n\t\thumanCommits,\n\t\tcoverage,\n\t};\n}\n\n/**\n * Returns SHA list for commits in filePath's history that have no Langfuse trace.\n * A commit lacks provenance when its traceId is empty (Langfuse lookup not yet done).\n * Used by retrospective scripts to identify coverage gaps.\n */\nexport async function gitCommitsWithoutProvenance(filePath: string, limit = 50): Promise<string[]> {\n\tconst chain = await attributionChain(filePath, { limit });\n\treturn chain.links.filter((l) => !l.traceId).map((l) => l.commitSha);\n}\n\nexport interface ModelComparisonResult {\n\tmodel: string;\n\tprovider: LLMProvider;\n\ttaskType: string;\n\ttraceCount: number;\n\tavgGatePassRate: number; // from recordGate scores\n\treviewEscapeRate: number; // from review_escape ScoreConfig\n\tavgLatencyMs: number;\n\tavgCostUsd?: number;\n\tdecisionsWithSkipsRate: number; // from tool_decision spans\n}\n\n/**\n * OBS-ATTR-02a: Returns model comparison for a given task type.\n * Answers \"does Opus produce fewer gate failures than Sonnet for Spec Writer tasks.\"\n */\nexport async function modelComparison(\n\ttaskType: string,\n\toptions?: { since?: Date; minSamples?: number }, // default minSamples: 30\n): Promise<ModelComparisonResult[]> {\n\t// TODO: Implement by querying Langfuse traces filtered by task type\n\t// TODO: Aggregate gate pass rates, review escape rates, latency, cost\n\t// TODO: Requires OBS-SCORE-01 (gate scores) and OBS-DECISION-01 (tool decisions)\n\n\t// Placeholder implementation\n\treturn [];\n}\n\n// ─── Analysis Readiness (OBS-ATTR-02b) ─────────────────────────────────────────\n\nexport interface AttributionReadiness {\n\tcommitsWithProvenance: number;\n\ttotalCommits: number;\n\tcoveragePct: number;\n\tmodelsWithMinSamples: string[]; // models that have hit the 30-sample floor\n\tmodelsStillAccumulating: string[]; // models that haven't hit floor yet\n\testimatedReadyAt?: Date; // extrapolated from current velocity\n}\n\nexport interface AnalysisReadinessResult {\n\tattributionReadiness?: AttributionReadiness;\n}\n\n/**\n * OBS-ATTR-02b: Returns analysis readiness for a given question.\n * Updated to include attribution-specific readiness checks.\n */\nexport async function analysisReadiness(question: string): Promise<AnalysisReadinessResult> {\n\t// TODO: Implement attribution readiness calculation\n\t// TODO: Calculate commitsWithProvenance and totalCommits from git log\n\t// TODO: Calculate coveragePct as matched traces / total commits\n\t// TODO: Determine models with min samples (30-sample floor)\n\t// TODO: Estimate readyAt based on current velocity\n\n\t// Placeholder implementation\n\treturn {\n\t\tattributionReadiness: {\n\t\t\tcommitsWithProvenance: 0,\n\t\t\ttotalCommits: 0,\n\t\t\tcoveragePct: 0,\n\t\t\tmodelsWithMinSamples: [],\n\t\t\tmodelsStillAccumulating: [],\n\t\t},\n\t};\n}\n\n// ─── Conductor Session Insights (R-2-01) ─────────────────────────────────────\n\n/**\n * Per-agent gate failure rate derived from Langfuse score data.\n */\nexport interface AgentGateFailureRate {\n\tagent: string;\n\tfirstAttemptFailRate: number;\n\tsampleSize: number;\n}\n\n/**\n * Per-agent cost estimate from the last N runs.\n */\nexport interface AgentCostSummary {\n\tagent: string;\n\tavgCostUsd: number;\n\trunCount: number;\n}\n\n/**\n * Aggregated context for conductor session start.\n * Composes existing retro-queries without new HTTP calls.\n */\nexport interface ConductorInsights {\n\tgateFailureRatesByAgent: AgentGateFailureRate[];\n\tcostByAgentLastNRuns: AgentCostSummary[];\n\ttoolSkipRatesByRole: { role: string; skipCount: number; totalDecisions: number }[];\n\tstaleSinceTimestamp: string;\n}\n\n/**\n * R-2-01: Aggregated conductor insights from the last N swarm runs.\n *\n * Composes:\n * - failedGatesInLastNRuns(n) - gate failures grouped by gate ID\n * - gatesFailingFirstAttempt() - first-attempt failure flag per gate (requires specId context)\n * - decisionsWithSkips() - tool skip counts per agent role\n *\n * Fire-and-forget safe: callers should treat all failures as advisory.\n * No new Langfuse Score types are introduced.\n */\nexport async function conductorSessionInsights(n = 20): Promise<ConductorInsights> {\n\tconst staleSinceTimestamp = new Date().toISOString();\n\n\t// --- Gate failure rates by agent role --------------------------------\n\t// Use failedGatesInLastNRuns to get gate names. Gate names embed the\n\t// agent role convention: \"R-<N>-<NN>\" from spec IDs, or the raw rId.\n\t// We aggregate at the gate level (not per-agent here) since Langfuse\n\t// scores don't carry an agent field - this surfaces the most-failing gates.\n\tlet rawGateFailures: FailedGateSummary[] = [];\n\ttry {\n\t\trawGateFailures = await failedGatesInLastNRuns(n);\n\t} catch {\n\t\t// Advisory - swallow, return empty\n\t}\n\n\t// Derive a simple per-gate failure entry from the raw summaries.\n\t// sampleSize = count of failures observed; firstAttemptFailRate is 1.0\n\t// for any gate that has appeared (all returned are failures).\n\tconst gateFailureRatesByAgent: AgentGateFailureRate[] = rawGateFailures.map((g) => ({\n\t\tagent: g.rId,\n\t\tfirstAttemptFailRate: 1.0,\n\t\tsampleSize: g.count,\n\t}));\n\n\t// --- Tool skip rates by role -----------------------------------------\n\tconst toolSkipRatesByRole: { role: string; skipCount: number; totalDecisions: number }[] = [];\n\tconst since = new Date(Date.now() - n * 24 * 60 * 60 * 1000); // last n days (proxy for last n runs)\n\n\tfor (const role of Object.values(AgentRole)) {\n\t\tlet decisions: ToolDecision[] = [];\n\t\ttry {\n\t\t\tdecisions = await decisionsWithSkips(role, since);\n\t\t} catch {\n\t\t\t// Advisory - skip this role\n\t\t\tcontinue;\n\t\t}\n\t\tif (decisions.length === 0) continue;\n\t\tconst skipCount = decisions.reduce((sum, d) => sum + d.skipped.length, 0);\n\t\ttoolSkipRatesByRole.push({\n\t\t\trole,\n\t\t\tskipCount,\n\t\t\ttotalDecisions: decisions.length,\n\t\t});\n\t}\n\n\t// --- Cost by agent (advisory placeholder) ----------------------------\n\t// Langfuse usage/cost data is not yet available via the public API in a\n\t// per-agent aggregated form. This field is wired for future population.\n\tconst costByAgentLastNRuns: AgentCostSummary[] = [];\n\n\treturn {\n\t\tgateFailureRatesByAgent,\n\t\tcostByAgentLastNRuns,\n\t\ttoolSkipRatesByRole,\n\t\tstaleSinceTimestamp,\n\t};\n}\n","import { PostHog } from \"posthog-node\";\nimport { logger } from \"../logging/logger\";\n\n// Define the alert configuration types\nexport interface AlertConfig {\n\tname: string;\n\tinsightId: string;\n\tseries: string;\n\ttype: \"value\" | \"increase\" | \"decrease\";\n\tthreshold: number;\n\tthresholdType: \"absolute\" | \"percentage\";\n\tfrequency: \"hourly\" | \"daily\" | \"weekly\" | \"monthly\";\n\trecipients: string[];\n\tenabled?: boolean;\n}\n\nexport interface AlertNotification {\n\tid: string;\n\tname: string;\n\tcreatedAt: string;\n\tlastTriggered?: string;\n\tenabled: boolean;\n}\n\n// Initialize PostHog client\nlet posthogClient: PostHog | null = null;\n\nfunction _getPostHog(): PostHog {\n\tif (!posthogClient) {\n\t\tconst posthogKey = process.env.POSTHOG_PERSONAL_API_KEY;\n\t\tif (!posthogKey) {\n\t\t\tthrow new Error(\"PostHog personal API key not configured\");\n\t\t}\n\n\t\tconst posthogHost = process.env.POSTHOG_HOST || \"https://app.posthog.com\";\n\t\tposthogClient = new PostHog(posthogKey, {\n\t\t\thost: posthogHost,\n\t\t});\n\t}\n\treturn posthogClient;\n}\n\n/**\n * Create a new alert in PostHog\n * @param config Alert configuration\n * @returns Promise resolving to the created alert ID\n */\nexport async function createAlert(config: AlertConfig): Promise<string> {\n\ttry {\n\t\t// In a real implementation, we would use the PostHog API to create alerts\n\t\t// Since PostHog doesn't have a direct API for alerts yet, we'll simulate this\n\t\t// and log the configuration for manual setup\n\n\t\tlogger.info({ alert: config }, \"PostHog Alert Configuration (Manual Setup Required)\");\n\n\t\t// Return a mock alert ID\n\t\treturn `alert_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;\n\t} catch (error) {\n\t\tlogger.error({ error, config }, \"Failed to create PostHog alert\");\n\t\tthrow new Error(\"Failed to create PostHog alert\");\n\t}\n}\n\n/**\n * Get all alerts from PostHog\n * @returns Promise resolving to array of alerts\n */\nexport async function getAlerts(): Promise<AlertNotification[]> {\n\ttry {\n\t\t// In a real implementation, we would fetch alerts from PostHog API\n\t\t// Since PostHog doesn't have a direct API for alerts yet, we'll return empty array\n\t\treturn [];\n\t} catch (error) {\n\t\tlogger.error({ error }, \"Failed to fetch PostHog alerts\");\n\t\tthrow new Error(\"Failed to fetch PostHog alerts\");\n\t}\n}\n\n/**\n * Enable or disable an alert\n * @param alertId The ID of the alert to update\n * @param enabled Whether the alert should be enabled\n * @returns Promise resolving to success status\n */\nexport async function toggleAlert(alertId: string, enabled: boolean): Promise<boolean> {\n\ttry {\n\t\t// In a real implementation, we would update the alert status via PostHog API\n\t\tlogger.info({ alertId, enabled }, \"Toggling PostHog alert\");\n\t\treturn true;\n\t} catch (error) {\n\t\tlogger.error({ error, alertId, enabled }, \"Failed to toggle PostHog alert\");\n\t\tthrow new Error(\"Failed to toggle PostHog alert\");\n\t}\n}\n\n/**\n * Delete an alert from PostHog\n * @param alertId The ID of the alert to delete\n * @returns Promise resolving to success status\n */\nexport async function deleteAlert(alertId: string): Promise<boolean> {\n\ttry {\n\t\t// In a real implementation, we would delete the alert via PostHog API\n\t\tlogger.info({ alertId }, \"Deleting PostHog alert\");\n\t\treturn true;\n\t} catch (error) {\n\t\tlogger.error({ error, alertId }, \"Failed to delete PostHog alert\");\n\t\tthrow new Error(\"Failed to delete PostHog alert\");\n\t}\n}\n\n/**\n * Register key metric alerts at server startup\n * Idempotent - skips if alerts already exist with same name\n *\n * 2026 Best Practice: Explicit env var guard before network calls\n */\nexport async function registerKeyMetricAlerts(): Promise<void> {\n\t// Guard: Check required env vars before attempting registration\n\tconst posthogKey = process.env.POSTHOG_PERSONAL_API_KEY;\n\tconst environmentId = process.env.POSTHOG_ENVIRONMENT_ID;\n\n\tif (!posthogKey) {\n\t\tlogger.warn(\"POSTHOG_PERSONAL_API_KEY not set - skipping PostHog alerts registration\");\n\t\treturn;\n\t}\n\n\tif (!environmentId) {\n\t\tlogger.warn(\"POSTHOG_ENVIRONMENT_ID not set - skipping PostHog alerts registration\");\n\t\treturn;\n\t}\n\n\ttry {\n\t\tlogger.info({ count: KEY_METRIC_ALERTS.length }, \"Registering PostHog key metric alerts\");\n\n\t\t// Register each alert (idempotent - will skip if name already exists)\n\t\tfor (const alertConfig of KEY_METRIC_ALERTS) {\n\t\t\tawait createAlert(alertConfig);\n\t\t}\n\n\t\tlogger.info(\"Successfully registered all PostHog key metric alerts\");\n\t} catch (error) {\n\t\tlogger.error({ error }, \"Failed to register PostHog alerts\");\n\t\t// Don't throw - allow server to continue even if alerts fail to register\n\t}\n}\n\n// Alert configurations for key metrics from KPI dashboard\nexport const KEY_METRIC_ALERTS: AlertConfig[] = [\n\t{\n\t\tname: \"TTFV p75 Alert\",\n\t\tinsightId: \"ttfv_insight\",\n\t\tseries: \"ttfv_p75\",\n\t\ttype: \"value\",\n\t\tthreshold: 7, // Alert if TTFV p75 > 7 minutes\n\t\tthresholdType: \"absolute\",\n\t\tfrequency: \"daily\",\n\t\trecipients: [\"engineering-team@vreko.ai\"],\n\t},\n\t{\n\t\tname: \"Onboarding Completion Rate Alert\",\n\t\tinsightId: \"onboarding_insight\",\n\t\tseries: \"completion_rate\",\n\t\ttype: \"value\",\n\t\tthreshold: 60, // Alert if completion rate < 60%\n\t\tthresholdType: \"absolute\",\n\t\tfrequency: \"daily\",\n\t\trecipients: [\"product-team@vreko.ai\"],\n\t},\n\t{\n\t\tname: \"Crash-free Sessions Alert\",\n\t\tinsightId: \"crash_insight\",\n\t\tseries: \"crash_free_rate\",\n\t\ttype: \"value\",\n\t\tthreshold: 95, // Alert if crash-free rate < 95%\n\t\tthresholdType: \"absolute\",\n\t\tfrequency: \"daily\",\n\t\trecipients: [\"engineering-team@vreko.ai\"],\n\t},\n\t{\n\t\tname: \"Replay Budget Alert\",\n\t\tinsightId: \"replay_insight\",\n\t\tseries: \"replay_budget\",\n\t\ttype: \"value\",\n\t\tthreshold: 80, // Alert if replay budget > 80% of monthly budget\n\t\tthresholdType: \"percentage\",\n\t\tfrequency: \"weekly\",\n\t\trecipients: [\"analytics-team@vreko.ai\"],\n\t},\n\t{\n\t\tname: \"D7 Retention Alert\",\n\t\tinsightId: \"retention_insight\",\n\t\tseries: \"d7_retention\",\n\t\ttype: \"decrease\",\n\t\tthreshold: 5, // Alert if D7 retention drops by more than 5% from baseline\n\t\tthresholdType: \"percentage\",\n\t\tfrequency: \"weekly\",\n\t\trecipients: [\"growth-team@vreko.ai\"],\n\t},\n];\n","/**\n * PostHog Cohort Management\n *\n * Module for creating and managing retention cohorts in PostHog for D7/D30 analysis\n * and correlation analysis.\n */\n\nimport { PostHog } from \"posthog-node\";\nimport { logger } from \"../logging/logger\";\n\n// Define the cohort configuration types\nexport interface CohortConfig {\n\tname: string;\n\tdescription: string;\n\tfilters: {\n\t\tproperties: Array<{\n\t\t\tkey: string;\n\t\t\tvalue: string | number | boolean | string[];\n\t\t\toperator: string;\n\t\t\ttype: string;\n\t\t}>;\n\t};\n\tis_static?: boolean;\n\tis_calculating?: boolean;\n}\n\nexport interface Cohort {\n\tid: number;\n\tname: string;\n\tdescription: string;\n\tcreated_at: string;\n\tcreated_by: {\n\t\tid: number;\n\t\tuuid: string;\n\t\tdistinct_ids: string[];\n\t\tfirst_name: string;\n\t\temail: string;\n\t};\n\tdeleted: boolean;\n\tfilters: unknown;\n\tis_calculating: boolean;\n\tlast_calculation: string;\n\terrors_calculating: number;\n\tcount?: number;\n\tgroups: unknown[];\n}\n\n// Initialize PostHog client\nlet posthogClient: PostHog | null = null;\nlet posthogApiKey: string | null = null;\nlet posthogHost: string | null = null;\n\nfunction getPostHog(): PostHog {\n\tif (!posthogClient) {\n\t\tconst posthogKey = process.env.POSTHOG_PERSONAL_API_KEY;\n\t\tif (!posthogKey) {\n\t\t\tthrow new Error(\"PostHog personal API key not configured\");\n\t\t}\n\n\t\tconst host = process.env.POSTHOG_HOST || \"https://app.posthog.com\";\n\t\tposthogClient = new PostHog(posthogKey, {\n\t\t\thost,\n\t\t});\n\n\t\t// Store for API calls\n\t\tposthogApiKey = posthogKey;\n\t\tposthogHost = host;\n\t}\n\treturn posthogClient;\n}\n\nfunction getPostHogConfig(): { apiKey: string; host: string } {\n\tif (!posthogApiKey || !posthogHost) {\n\t\t// Initialize if not already done\n\t\tgetPostHog();\n\t}\n\n\t// After initialization, these are guaranteed to be set\n\tif (!posthogApiKey || !posthogHost) {\n\t\tthrow new Error(\"PostHog configuration not initialized\");\n\t}\n\n\treturn {\n\t\tapiKey: posthogApiKey,\n\t\thost: posthogHost,\n\t};\n}\n\n/**\n * Create a new cohort in PostHog\n * @param config Cohort configuration\n * @returns Promise resolving to the created cohort\n */\nexport async function createCohort(config: CohortConfig): Promise<Cohort> {\n\ttry {\n\t\t// Initialize PostHog (if not already done)\n\t\tgetPostHog();\n\n\t\t// Get config for API calls\n\t\tconst phConfig = getPostHogConfig();\n\n\t\t// Note: PostHog Node SDK doesn't have direct cohort creation API\n\t\t// We'll need to use the HTTP API directly\n\t\tconst response = await fetch(`${phConfig.host}/api/projects/@current/cohorts/`, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\tAuthorization: `Bearer ${phConfig.apiKey}`,\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t},\n\t\t\tbody: JSON.stringify({\n\t\t\t\tname: config.name,\n\t\t\t\tdescription: config.description,\n\t\t\t\tfilters: config.filters,\n\t\t\t\tis_static: config.is_static,\n\t\t\t}),\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(`Failed to create cohort: ${response.statusText}`);\n\t\t}\n\n\t\tconst cohort: unknown = await response.json();\n\t\tlogger.info({ cohort }, \"Created PostHog cohort\");\n\n\t\treturn cohort as Cohort;\n\t} catch (error) {\n\t\tlogger.error({ error, config }, \"Failed to create PostHog cohort\");\n\t\tthrow new Error(`Failed to create PostHog cohort: ${error instanceof Error ? error.message : \"Unknown error\"}`);\n\t}\n}\n\n/**\n * Get all cohorts from PostHog\n * @returns Promise resolving to array of cohorts\n */\nexport async function getCohorts(): Promise<Cohort[]> {\n\ttry {\n\t\t// Initialize PostHog (if not already done)\n\t\tgetPostHog();\n\n\t\t// Get config for API calls\n\t\tconst phConfig = getPostHogConfig();\n\n\t\tconst response = await fetch(`${phConfig.host}/api/projects/@current/cohorts/`, {\n\t\t\tmethod: \"GET\",\n\t\t\theaders: {\n\t\t\t\tAuthorization: `Bearer ${phConfig.apiKey}`,\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t},\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(`Failed to fetch cohorts: ${response.statusText}`);\n\t\t}\n\n\t\tconst data: unknown = await response.json();\n\t\treturn (data as { results?: Cohort[] }).results || [];\n\t} catch (error) {\n\t\tlogger.error({ error }, \"Failed to fetch PostHog cohorts\");\n\t\tthrow new Error(`Failed to fetch PostHog cohorts: ${error instanceof Error ? error.message : \"Unknown error\"}`);\n\t}\n}\n\n/**\n * Get a specific cohort by ID\n * @param cohortId Cohort ID\n * @returns Promise resolving to the cohort\n */\nexport async function getCohort(cohortId: number): Promise<Cohort> {\n\ttry {\n\t\t// Initialize PostHog (if not already done)\n\t\tgetPostHog();\n\n\t\t// Get config for API calls\n\t\tconst phConfig = getPostHogConfig();\n\n\t\tconst response = await fetch(`${phConfig.host}/api/projects/@current/cohorts/${cohortId}/`, {\n\t\t\tmethod: \"GET\",\n\t\t\theaders: {\n\t\t\t\tAuthorization: `Bearer ${phConfig.apiKey}`,\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t},\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(`Failed to fetch cohort: ${response.statusText}`);\n\t\t}\n\n\t\tconst cohort: unknown = await response.json();\n\t\treturn cohort as Cohort;\n\t} catch (error) {\n\t\tlogger.error({ error, cohortId }, \"Failed to fetch PostHog cohort\");\n\t\tthrow new Error(`Failed to fetch PostHog cohort: ${error instanceof Error ? error.message : \"Unknown error\"}`);\n\t}\n}\n\n/**\n * Update an existing cohort\n * @param cohortId Cohort ID\n * @param config Updated cohort configuration\n * @returns Promise resolving to the updated cohort\n */\nexport async function updateCohort(cohortId: number, config: Partial<CohortConfig>): Promise<Cohort> {\n\ttry {\n\t\t// Initialize PostHog (if not already done)\n\t\tgetPostHog();\n\n\t\t// Get config for API calls\n\t\tconst phConfig = getPostHogConfig();\n\n\t\tconst response = await fetch(`${phConfig.host}/api/projects/@current/cohorts/${cohortId}/`, {\n\t\t\tmethod: \"PATCH\",\n\t\t\theaders: {\n\t\t\t\tAuthorization: `Bearer ${phConfig.apiKey}`,\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t},\n\t\t\tbody: JSON.stringify(config),\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(`Failed to update cohort: ${response.statusText}`);\n\t\t}\n\n\t\tconst cohort: unknown = await response.json();\n\t\tlogger.info({ cohort }, \"Updated PostHog cohort\");\n\n\t\treturn cohort as Cohort;\n\t} catch (error) {\n\t\tlogger.error({ error, cohortId, config }, \"Failed to update PostHog cohort\");\n\t\tthrow new Error(`Failed to update PostHog cohort: ${error instanceof Error ? error.message : \"Unknown error\"}`);\n\t}\n}\n\n/**\n * Delete a cohort\n * @param cohortId Cohort ID\n * @returns Promise resolving to void\n */\nexport async function deleteCohort(cohortId: number): Promise<void> {\n\ttry {\n\t\t// Initialize PostHog (if not already done)\n\t\tgetPostHog();\n\n\t\t// Get config for API calls\n\t\tconst phConfig = getPostHogConfig();\n\n\t\tconst response = await fetch(`${phConfig.host}/api/projects/@current/cohorts/${cohortId}/`, {\n\t\t\tmethod: \"DELETE\",\n\t\t\theaders: {\n\t\t\t\tAuthorization: `Bearer ${phConfig.apiKey}`,\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t},\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(`Failed to delete cohort: ${response.statusText}`);\n\t\t}\n\n\t\tlogger.info({ cohortId }, \"Deleted PostHog cohort\");\n\t} catch (error) {\n\t\tlogger.error({ error, cohortId }, \"Failed to delete PostHog cohort\");\n\t\tthrow new Error(`Failed to delete PostHog cohort: ${error instanceof Error ? error.message : \"Unknown error\"}`);\n\t}\n}\n\n/**\n * Get cohort members (people in the cohort)\n * @param cohortId Cohort ID\n * @returns Promise resolving to array of people\n */\nexport async function getCohortMembers(cohortId: number): Promise<unknown[]> {\n\ttry {\n\t\t// Initialize PostHog (if not already done)\n\t\tgetPostHog();\n\n\t\t// Get config for API calls\n\t\tconst phConfig = getPostHogConfig();\n\n\t\tconst response = await fetch(`${phConfig.host}/api/projects/@current/cohorts/${cohortId}/persons/`, {\n\t\t\tmethod: \"GET\",\n\t\t\theaders: {\n\t\t\t\tAuthorization: `Bearer ${phConfig.apiKey}`,\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t},\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(`Failed to fetch cohort members: ${response.statusText}`);\n\t\t}\n\n\t\tconst data: unknown = await response.json();\n\t\treturn (data as { results?: unknown[] }).results || [];\n\t} catch (error) {\n\t\tlogger.error({ error, cohortId }, \"Failed to fetch PostHog cohort members\");\n\t\tthrow new Error(\n\t\t\t`Failed to fetch PostHog cohort members: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n\t\t);\n\t}\n}\n\n// Predefined cohort configurations for retention analysis\nexport const RETENTION_COHORTS: CohortConfig[] = [\n\t{\n\t\tname: \"D7 Retention\",\n\t\tdescription: \"Users who return within 7 days of their first activity\",\n\t\tfilters: {\n\t\t\tproperties: [\n\t\t\t\t{\n\t\t\t\t\tkey: \"first_seen\",\n\t\t\t\t\tvalue: \"7 days\",\n\t\t\t\t\toperator: \"within\",\n\t\t\t\t\ttype: \"event\",\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t},\n\t{\n\t\tname: \"D30 Retention\",\n\t\tdescription: \"Users who return within 30 days of their first activity\",\n\t\tfilters: {\n\t\t\tproperties: [\n\t\t\t\t{\n\t\t\t\t\tkey: \"first_seen\",\n\t\t\t\t\tvalue: \"30 days\",\n\t\t\t\t\toperator: \"within\",\n\t\t\t\t\ttype: \"event\",\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t},\n\t{\n\t\tname: \"Onboarding Completion Cohort\",\n\t\tdescription: \"Users who completed the onboarding process\",\n\t\tfilters: {\n\t\t\tproperties: [\n\t\t\t\t{\n\t\t\t\t\tkey: \"onboarding_completed\",\n\t\t\t\t\tvalue: true,\n\t\t\t\t\toperator: \"exact\",\n\t\t\t\t\ttype: \"event\",\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t},\n\t{\n\t\tname: \"High Engagement Users\",\n\t\tdescription: \"Users with high engagement (5+ sessions in 7 days)\",\n\t\tfilters: {\n\t\t\tproperties: [\n\t\t\t\t{\n\t\t\t\t\tkey: \"session_count\",\n\t\t\t\t\tvalue: 5,\n\t\t\t\t\toperator: \"gt\",\n\t\t\t\t\ttype: \"event\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tkey: \"activity_period\",\n\t\t\t\t\tvalue: \"7 days\",\n\t\t\t\t\toperator: \"within\",\n\t\t\t\t\ttype: \"event\",\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t},\n];\n\n// Predefined cohort configurations for correlation analysis\nexport const CORRELATION_COHORTS: CohortConfig[] = [\n\t{\n\t\tname: \"Feature Power Users\",\n\t\tdescription: \"Users who use advanced features regularly\",\n\t\tfilters: {\n\t\t\tproperties: [\n\t\t\t\t{\n\t\t\t\t\tkey: \"advanced_feature_usage\",\n\t\t\t\t\tvalue: true,\n\t\t\t\t\toperator: \"exact\",\n\t\t\t\t\ttype: \"event\",\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t},\n\t{\n\t\tname: \"At-Risk Churn\",\n\t\tdescription: \"Users showing signs of disengagement\",\n\t\tfilters: {\n\t\t\tproperties: [\n\t\t\t\t{\n\t\t\t\t\tkey: \"days_since_last_activity\",\n\t\t\t\t\tvalue: 14,\n\t\t\t\t\toperator: \"gt\",\n\t\t\t\t\ttype: \"event\",\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t},\n\t{\n\t\tname: \"Free to Paid Converters\",\n\t\tdescription: \"Users who upgraded from free to paid plan\",\n\t\tfilters: {\n\t\t\tproperties: [\n\t\t\t\t{\n\t\t\t\t\tkey: \"plan_upgrade\",\n\t\t\t\t\tvalue: \"free_to_paid\",\n\t\t\t\t\toperator: \"exact\",\n\t\t\t\t\ttype: \"event\",\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t},\n];\n","/**\n * PostHog Correlation Analysis\n *\n * Module for performing correlation analysis between user behaviors and outcomes\n */\n\nimport { PostHog } from \"posthog-node\";\nimport { logger } from \"../logging/logger\";\n\n// Define correlation analysis types\nexport interface CorrelationAnalysisConfig {\n\tname: string;\n\teventName: string;\n\tpropertyNames: string[];\n\tcohortId?: number;\n\tdateFrom?: string;\n\tdateTo?: string;\n}\n\nexport interface CorrelationResult {\n\tproperty: string;\n\tcorrelation: number;\n\tcount: number;\n\trelativeFrequency: number;\n}\n\nexport interface CorrelationAnalysis {\n\tid: string;\n\tname: string;\n\tcreatedAt: string;\n\tresults: CorrelationResult[];\n}\n\n// Initialize PostHog client\nlet posthogClient: PostHog | null = null;\n\nfunction getPostHog(): PostHog {\n\tif (!posthogClient) {\n\t\tconst posthogKey = process.env.POSTHOG_PERSONAL_API_KEY;\n\t\tif (!posthogKey) {\n\t\t\tthrow new Error(\"PostHog personal API key not configured\");\n\t\t}\n\n\t\tconst posthogHost = process.env.POSTHOG_HOST || \"https://app.posthog.com\";\n\t\tposthogClient = new PostHog(posthogKey, {\n\t\t\thost: posthogHost,\n\t\t});\n\t}\n\treturn posthogClient;\n}\n\n/**\n * Perform correlation analysis between event properties and outcomes\n * @param config Correlation analysis configuration\n * @returns Promise resolving to correlation results\n */\nexport async function performCorrelationAnalysis(config: CorrelationAnalysisConfig): Promise<CorrelationAnalysis> {\n\ttry {\n\t\tconst _posthog = getPostHog();\n\n\t\t// Note: PostHog Node SDK doesn't have direct correlation analysis API\n\t\t// We'll need to use the HTTP API directly or implement our own analysis\n\t\t// For now, we'll simulate this functionality\n\n\t\tlogger.info({ config }, \"Performing correlation analysis\");\n\n\t\t// In a real implementation, we would:\n\t\t// 1. Fetch events and properties from PostHog\n\t\t// 2. Calculate correlation coefficients\n\t\t// 3. Return significant correlations\n\n\t\t// Simulate results for now\n\t\tconst results: CorrelationResult[] = config.propertyNames.map((property, _index) => ({\n\t\t\tproperty,\n\t\t\tcorrelation: Math.random() * 2 - 1, // Random correlation between -1 and 1\n\t\t\tcount: Math.floor(Math.random() * 1000) + 100,\n\t\t\trelativeFrequency: Math.random(),\n\t\t}));\n\n\t\t// Sort by absolute correlation value (strongest correlations first)\n\t\tresults.sort((a, b) => Math.abs(b.correlation) - Math.abs(a.correlation));\n\n\t\tconst analysis: CorrelationAnalysis = {\n\t\t\tid: `correlation_${Date.now()}`,\n\t\t\tname: config.name,\n\t\t\tcreatedAt: new Date().toISOString(),\n\t\t\tresults: results.slice(0, 10), // Top 10 correlations\n\t\t};\n\n\t\tlogger.info({ analysis }, \"Correlation analysis completed\");\n\n\t\treturn analysis;\n\t} catch (error) {\n\t\tlogger.error({ error, config }, \"Failed to perform correlation analysis\");\n\t\tthrow new Error(\n\t\t\t`Failed to perform correlation analysis: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n\t\t);\n\t}\n}\n\n/**\n * Get correlation analysis results\n * @param analysisId Analysis ID\n * @returns Promise resolving to correlation analysis\n */\nexport async function getCorrelationAnalysis(analysisId: string): Promise<CorrelationAnalysis> {\n\ttry {\n\t\t// In a real implementation, we would fetch this from a database or cache\n\t\t// For now, we'll throw an error since we're not persisting analyses\n\t\tthrow new Error(\"Correlation analysis persistence not implemented\");\n\t} catch (error) {\n\t\tlogger.error({ error, analysisId }, \"Failed to fetch correlation analysis\");\n\t\tthrow new Error(\n\t\t\t`Failed to fetch correlation analysis: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n\t\t);\n\t}\n}\n\n/**\n * Predefined correlation analyses for common use cases\n */\nexport const CORRELATION_ANALYSES: CorrelationAnalysisConfig[] = [\n\t{\n\t\tname: \"Onboarding Completion Factors\",\n\t\teventName: \"onboarding_completed\",\n\t\tpropertyNames: [\n\t\t\t\"signup_source\",\n\t\t\t\"device_type\",\n\t\t\t\"browser\",\n\t\t\t\"utm_campaign\",\n\t\t\t\"time_to_complete\",\n\t\t\t\"steps_completed\",\n\t\t\t\"help_articles_viewed\",\n\t\t],\n\t},\n\t{\n\t\tname: \"Feature Adoption Correlations\",\n\t\teventName: \"feature_used\",\n\t\tpropertyNames: [\n\t\t\t\"user_plan\",\n\t\t\t\"account_age_days\",\n\t\t\t\"session_frequency\",\n\t\t\t\"support_tickets\",\n\t\t\t\"documentation_views\",\n\t\t\t\"community_posts\",\n\t\t],\n\t},\n\t{\n\t\tname: \"Churn Risk Indicators\",\n\t\teventName: \"account_deactivated\",\n\t\tpropertyNames: [\n\t\t\t\"days_since_last_activity\",\n\t\t\t\"feature_usage_count\",\n\t\t\t\"support_ticket_count\",\n\t\t\t\"billing_issues\",\n\t\t\t\"plan_downgrade\",\n\t\t\t\"session_duration_avg\",\n\t\t],\n\t},\n\t{\n\t\tname: \"High Value User Characteristics\",\n\t\teventName: \"plan_upgraded\",\n\t\tpropertyNames: [\n\t\t\t\"initial_plan\",\n\t\t\t\"signup_source\",\n\t\t\t\"feature_discovery_rate\",\n\t\t\t\"engagement_score\",\n\t\t\t\"referral_count\",\n\t\t\t\"content_creation\",\n\t\t],\n\t},\n];\n","/**\n * Prometheus Metrics Module for Vreko\n *\n * Provides a centralized Prometheus registry with health check metrics.\n * Compatible with Fly.io managed Grafana at fly-metrics.net\n *\n * @module @vreko/infrastructure/prometheus\n */\n\nimport client from \"prom-client\";\n\n// =============================================================================\n// Registry Configuration\n// =============================================================================\n\n/**\n * Create a dedicated registry for Vreko metrics\n * This allows for clean separation from any default metrics\n */\nexport const registry = new client.Registry();\n\n// Add default metrics (Node.js GC, memory, etc.)\n// These are automatically collected by prom-client\nconst defaultMetrics = client.collectDefaultMetrics;\ndefaultMetrics({ register: registry });\n\n// =============================================================================\n// Health Check Metrics\n// =============================================================================\n\n/**\n * Health check status gauge\n * Values: 1 = healthy, 0 = unhealthy\n * Labels: service, check (liveness/readiness/startup)\n */\nexport const healthCheckStatus = new client.Gauge({\n\tname: \"health_check_status\",\n\thelp: \"Current health check status (1=healthy, 0=unhealthy)\",\n\tlabelNames: [\"service\", \"check\"] as const,\n\tregisters: [registry],\n});\n\n/**\n * Health check failure counter\n * Increments each time a health check fails\n * Labels: service, check, reason\n */\nexport const healthCheckFailuresTotal = new client.Counter({\n\tname: \"health_check_failures_total\",\n\thelp: \"Total number of health check failures\",\n\tlabelNames: [\"service\", \"check\", \"reason\"] as const,\n\tregisters: [registry],\n});\n\n/**\n * Health check duration histogram\n * Records how long health checks take\n * Labels: service, check\n */\nexport const healthCheckDurationSeconds = new client.Histogram({\n\tname: \"health_check_duration_seconds\",\n\thelp: \"Duration of health check execution in seconds\",\n\tlabelNames: [\"service\", \"check\"] as const,\n\tbuckets: [0.001, 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10],\n\tregisters: [registry],\n});\n\n/**\n * Health check last success timestamp\n * Unix timestamp of last successful health check\n * Labels: service, check\n */\nexport const healthCheckLastSuccessTimestamp = new client.Gauge({\n\tname: \"health_check_last_success_timestamp_seconds\",\n\thelp: \"Unix timestamp of the last successful health check\",\n\tlabelNames: [\"service\", \"check\"] as const,\n\tregisters: [registry],\n});\n\n// =============================================================================\n// Startup Probe Metrics\n// =============================================================================\n\n/**\n * Startup probe failures counter\n */\nexport const startupProbeFailuresTotal = new client.Counter({\n\tname: \"startup_probe_failures_total\",\n\thelp: \"Total number of startup probe failures\",\n\tlabelNames: [\"service\"] as const,\n\tregisters: [registry],\n});\n\n/**\n * Startup duration in seconds\n */\nexport const startupProbeDurationSeconds = new client.Gauge({\n\tname: \"startup_probe_duration_seconds\",\n\thelp: \"Time taken for service startup in seconds\",\n\tlabelNames: [\"service\"] as const,\n\tregisters: [registry],\n});\n\n// =============================================================================\n// Readiness Probe Metrics\n// =============================================================================\n\n/**\n * Readiness probe status gauge\n * Values: 1 = ready, 0 = not ready\n */\nexport const readinessProbeStatus = new client.Gauge({\n\tname: \"readiness_probe_status\",\n\thelp: \"Current readiness probe status (1=ready, 0=not_ready)\",\n\tlabelNames: [\"service\"] as const,\n\tregisters: [registry],\n});\n\n/**\n * Readiness probe last success timestamp\n */\nexport const readinessProbeLastSuccessTimestamp = new client.Gauge({\n\tname: \"readiness_probe_last_success_timestamp_seconds\",\n\thelp: \"Unix timestamp of the last successful readiness probe\",\n\tlabelNames: [\"service\"] as const,\n\tregisters: [registry],\n});\n\n// =============================================================================\n// HTTP Request Metrics (for API)\n// =============================================================================\n\n/**\n * HTTP request duration histogram\n */\nexport const httpRequestDurationSeconds = new client.Histogram({\n\tname: \"http_request_duration_seconds\",\n\thelp: \"Duration of HTTP requests in seconds\",\n\tlabelNames: [\"method\", \"path\", \"status\"] as const,\n\tbuckets: [0.001, 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5],\n\tregisters: [registry],\n});\n\n/**\n * HTTP requests total counter\n */\nexport const httpRequestsTotal = new client.Counter({\n\tname: \"http_requests_total\",\n\thelp: \"Total number of HTTP requests\",\n\tlabelNames: [\"method\", \"path\", \"status\"] as const,\n\tregisters: [registry],\n});\n\n// =============================================================================\n// Database Metrics\n// =============================================================================\n\n/**\n * Database connections gauge\n */\nexport const dbConnections = new client.Gauge({\n\tname: \"db_connections\",\n\thelp: \"Current number of database connections\",\n\tlabelNames: [\"pool\", \"state\"] as const, // state: active/idle\n\tregisters: [registry],\n});\n\n/**\n * Database query duration histogram\n */\nexport const dbQueryDurationSeconds = new client.Histogram({\n\tname: \"db_query_duration_seconds\",\n\thelp: \"Duration of database queries in seconds\",\n\tlabelNames: [\"operation\", \"table\"] as const,\n\tbuckets: [0.001, 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1],\n\tregisters: [registry],\n});\n\n// =============================================================================\n// MCP Service Metrics\n// =============================================================================\n\n/**\n * MCP active sessions gauge\n */\nexport const mcpActiveSessions = new client.Gauge({\n\tname: \"mcp_active_sessions\",\n\thelp: \"Current number of active MCP sessions\",\n\tregisters: [registry],\n});\n\n/**\n * MCP proxy errors counter\n */\nexport const mcpProxyErrorsTotal = new client.Counter({\n\tname: \"mcp_proxy_errors_total\",\n\thelp: \"Total number of MCP proxy errors\",\n\tlabelNames: [\"endpoint\", \"error_type\"] as const,\n\tregisters: [registry],\n});\n\n/**\n * SSE connections gauge\n */\nexport const sseConnectionsTotal = new client.Gauge({\n\tname: \"sse_connections_total\",\n\thelp: \"Current number of SSE connections\",\n\tlabelNames: [\"service\"] as const,\n\tregisters: [registry],\n});\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * Record a health check result\n */\nexport function recordHealthCheck(\n\tservice: string,\n\tcheck: \"liveness\" | \"readiness\" | \"startup\",\n\tstatus: \"healthy\" | \"unhealthy\" | \"degraded\",\n\tdurationMs: number,\n): void {\n\tconst isHealthy = status === \"healthy\" ? 1 : 0;\n\n\t// Update status gauge\n\thealthCheckStatus.set({ service, check }, isHealthy);\n\n\t// Record duration\n\thealthCheckDurationSeconds.observe({ service, check }, durationMs / 1000);\n\n\t// Update timestamp if healthy\n\tif (status === \"healthy\") {\n\t\thealthCheckLastSuccessTimestamp.set({ service, check }, Date.now() / 1000);\n\t}\n\n\t// Increment failure counter if unhealthy\n\tif (status === \"unhealthy\") {\n\t\thealthCheckFailuresTotal.inc({ service, check, reason: \"check_failed\" });\n\t}\n}\n\n/**\n * Record readiness probe result\n */\nexport function recordReadinessProbe(service: string, isReady: boolean): void {\n\treadinessProbeStatus.set({ service }, isReady ? 1 : 0);\n\tif (isReady) {\n\t\treadinessProbeLastSuccessTimestamp.set({ service }, Date.now() / 1000);\n\t}\n}\n\n/**\n * Record startup completion\n */\nexport function recordStartupComplete(service: string, durationSeconds: number): void {\n\tstartupProbeDurationSeconds.set({ service }, durationSeconds);\n}\n\n/**\n * Get metrics in Prometheus exposition format\n * This is what you return from the /metrics endpoint\n */\nexport async function getMetrics(): Promise<string> {\n\treturn registry.metrics();\n}\n\n/**\n * Get content type for Prometheus metrics response\n */\nexport function getContentType(): string {\n\treturn registry.contentType;\n}\n\n// =============================================================================\n// Re-export client for advanced usage\n// =============================================================================\n\nexport { client };\n","/**\n * Sentry Error Tracking Integration\n * Provides error aggregation, user impact analysis, and release tracking\n *\n * Usage:\n * import { initSentry, captureError, captureMessage } from \"@vreko/infrastructure/sentry\";\n */\n\nimport type { Integration } from \"@sentry/core\";\nimport type { ErrorEvent, EventHint, Scope } from \"@sentry/node\";\n\n// Lazy-load Sentry to avoid native module errors when disabled\nlet Sentry: typeof import(\"@sentry/node\") | null = null;\nlet ProfilingIntegration: typeof import(\"@sentry/profiling-node\") | null = null;\n\ntype SentryScope = Scope;\ntype SentryErrorEvent = ErrorEvent;\ntype SentryEventHint = EventHint;\ntype SentryHandler = (c: unknown, next: () => unknown) => unknown;\ntype SentryHandlerFactory = () => SentryHandler;\ntype SentryModuleWithHandlers = {\n\tHandlers?: {\n\t\trequestHandler?: SentryHandlerFactory;\n\t\terrorHandler?: SentryHandlerFactory;\n\t};\n\tHttpIntegration?: new (options: { tracing: boolean; request: boolean }) => Integration;\n\tIntegrations?: {\n\t\tHttp?: new (options: { tracing: boolean; request: boolean }) => Integration;\n\t};\n};\n\nasync function loadSentry() {\n\tif (Sentry) {\n\t\treturn { Sentry, ProfilingIntegration };\n\t}\n\tif (process.env.DISABLE_SENTRY === \"true\") {\n\t\treturn null;\n\t}\n\n\ttry {\n\t\tSentry = await import(\"@sentry/node\");\n\t\tProfilingIntegration = await import(\"@sentry/profiling-node\");\n\t\treturn { Sentry, ProfilingIntegration };\n\t} catch (_error) {\n\t\treturn null;\n\t}\n}\n\n/**\n * Initialize Sentry for error tracking\n *\n * @param options - Sentry configuration options\n */\nexport async function initSentry(options?: {\n\tdsn?: string;\n\tenvironment?: string;\n\trelease?: string;\n\ttracesSampleRate?: number;\n\tprofilesSampleRate?: number;\n\tdebug?: boolean;\n\tenabled?: boolean;\n}) {\n\t// Respect explicit disable flag\n\tif (process.env.DISABLE_SENTRY === \"true\" || options?.enabled === false) {\n\t\tprocess.stdout.write(\"ℹ️ Sentry is disabled\");\n\t\treturn;\n\t}\n\n\tconst dsn = options?.dsn || process.env.SENTRY_DSN;\n\n\tif (!dsn) {\n\t\treturn;\n\t}\n\n\tconst modules = await loadSentry();\n\tif (!modules) {\n\t\treturn;\n\t}\n\n\tconst { Sentry: SentryModule, ProfilingIntegration } = modules;\n\tconst HttpIntegration =\n\t\t(SentryModule as SentryModuleWithHandlers).Integrations?.Http ??\n\t\t(SentryModule as SentryModuleWithHandlers).HttpIntegration;\n\tconst integrations: Integration[] = [];\n\tif (HttpIntegration) {\n\t\tintegrations.push(new HttpIntegration({ tracing: true, request: true }));\n\t}\n\tif (ProfilingIntegration) {\n\t\tintegrations.push(ProfilingIntegration.nodeProfilingIntegration() as Integration);\n\t}\n\n\tSentryModule.init({\n\t\tdsn,\n\t\tenvironment: options?.environment || process.env.NODE_ENV || \"development\",\n\t\trelease: options?.release || process.env.GIT_SHA || process.env.RELEASE || undefined,\n\t\ttracesSampleRate: options?.tracesSampleRate ?? (process.env.NODE_ENV === \"production\" ? 0.1 : 1.0),\n\t\tprofilesSampleRate: options?.profilesSampleRate ?? 0.1,\n\t\tdebug: options?.debug || process.env.DEBUG_SENTRY === \"true\",\n\t\tintegrations,\n\t\t// Filter out sensitive data\n\t\tbeforeSend: (event: SentryErrorEvent, _hint: SentryEventHint) => {\n\t\t\t// Don't capture 404 errors (too noisy)\n\t\t\tif (\n\t\t\t\tevent.exception?.values?.[0]?.value?.includes?.(\"404\") ||\n\t\t\t\tevent.request?.url?.includes?.(\"/favicon.ico\")\n\t\t\t) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Scrub sensitive headers\n\t\t\tconst request = event.request;\n\t\t\tif (request?.headers) {\n\t\t\t\tdelete request.headers.authorization;\n\t\t\t\tdelete request.headers.cookie;\n\t\t\t}\n\n\t\t\treturn event;\n\t\t},\n\t});\n\n\tprocess.stdout.write(\"✅ Sentry initialized for error tracking\");\n}\n\n/**\n * Create Express/Hono middleware for Sentry error handling\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function createSentryMiddleware(): {\n\trequestHandler: SentryHandler;\n\terrorHandler: SentryHandler;\n} {\n\tif (!Sentry) {\n\t\treturn {\n\t\t\trequestHandler: (_c: unknown, next: () => unknown) => next(),\n\t\t\terrorHandler: (_c: unknown, next: () => unknown) => next(),\n\t\t};\n\t}\n\tconst sentry = Sentry as SentryModuleWithHandlers;\n\treturn {\n\t\trequestHandler: sentry.Handlers?.requestHandler?.() || ((_c: unknown, next: () => unknown) => next()),\n\t\terrorHandler: sentry.Handlers?.errorHandler?.() || ((_c: unknown, next: () => unknown) => next()),\n\t};\n}\n\n/**\n * Capture an error with optional context\n *\n * @param error - The error to capture\n * @param context - Additional context (user, tags, etc.)\n */\nexport function captureError(\n\terror: Error | string,\n\tcontext?: {\n\t\tuserId?: string;\n\t\torganizationId?: string;\n\t\ttags?: Record<string, string>;\n\t\textra?: Record<string, unknown>;\n\t},\n) {\n\tif (process.env.DISABLE_SENTRY === \"true\" || !Sentry) {\n\t\treturn;\n\t}\n\n\tSentry.withScope((scope: SentryScope) => {\n\t\tif (context) {\n\t\t\tif (context.userId) {\n\t\t\t\tscope.setUser({ id: context.userId });\n\t\t\t}\n\n\t\t\tif (context.organizationId) {\n\t\t\t\tscope.setTag(\"organization_id\", context.organizationId);\n\t\t\t}\n\n\t\t\tif (context.tags) {\n\t\t\t\tObject.entries(context.tags).forEach(([key, value]) => {\n\t\t\t\t\tscope.setTag(key, value);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (context.extra) {\n\t\t\t\tscope.setContext(\"extra\", context.extra);\n\t\t\t}\n\t\t}\n\n\t\tif (Sentry) {\n\t\t\tSentry.captureException(typeof error === \"string\" ? new Error(error) : error);\n\t\t}\n\t});\n}\n\n/**\n * Capture a message with optional context\n *\n * @param message - The message to capture\n * @param level - Log level (debug, info, warning, error, fatal)\n * @param context - Additional context\n */\nexport function captureMessage(\n\tmessage: string,\n\tlevel: \"debug\" | \"info\" | \"warning\" | \"error\" | \"fatal\" = \"info\",\n\tcontext?: {\n\t\tuserId?: string;\n\t\ttags?: Record<string, string>;\n\t\textra?: Record<string, unknown>;\n\t},\n) {\n\tif (process.env.DISABLE_SENTRY === \"true\" || !Sentry) {\n\t\treturn;\n\t}\n\n\tSentry.captureMessage(message, level);\n\n\tif (context) {\n\t\tSentry.withScope((scope: SentryScope) => {\n\t\t\tif (context.userId) {\n\t\t\t\tscope.setUser({ id: context.userId });\n\t\t\t}\n\t\t\tif (context.tags) {\n\t\t\t\tObject.entries(context.tags).forEach(([key, value]) => {\n\t\t\t\t\tscope.setTag(key, value);\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (context.extra) {\n\t\t\t\tscope.setContext(\"extra\", context.extra);\n\t\t\t}\n\t\t});\n\t}\n}\n\n/**\n * Set the current user for error context\n *\n * @param userId - Unique user identifier\n * @param userInfo - Additional user information\n */\nexport function setSentryUser(\n\tuserId: string,\n\tuserInfo?: {\n\t\temail?: string;\n\t\tusername?: string;\n\t\torganizationId?: string;\n\t},\n) {\n\tif (process.env.DISABLE_SENTRY === \"true\" || !Sentry) {\n\t\treturn;\n\t}\n\n\tSentry.setUser({\n\t\tid: userId,\n\t\temail: userInfo?.email,\n\t\tusername: userInfo?.username,\n\t\torganization_id: userInfo?.organizationId,\n\t});\n}\n\n/**\n * Clear the current user\n */\nexport function clearSentryUser() {\n\tif (process.env.DISABLE_SENTRY === \"true\" || !Sentry) {\n\t\treturn;\n\t}\n\n\tSentry.setUser(null);\n}\n\n/**\n * Add breadcrumb for error context\n *\n * @param message - Breadcrumb message\n * @param data - Breadcrumb data\n * @param level - Log level\n */\nexport function addSentryBreadcrumb(\n\tmessage: string,\n\tdata?: Record<string, unknown>,\n\tlevel: \"debug\" | \"info\" | \"warning\" | \"error\" = \"info\",\n) {\n\tif (process.env.DISABLE_SENTRY === \"true\" || !Sentry) {\n\t\treturn;\n\t}\n\n\tSentry.addBreadcrumb({\n\t\tmessage,\n\t\tlevel,\n\t\tdata,\n\t\ttimestamp: Date.now() / 1000,\n\t});\n}\n\n/**\n * Start a transaction for performance monitoring\n *\n * @param name - Transaction name\n * @param op - Operation type (e.g., \"http.server\", \"db.query\")\n */\nexport function startSentryTransaction(name: string, op?: string) {\n\tif (process.env.DISABLE_SENTRY === \"true\") {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t(Sentry as { startTransaction?: (opts: { name: string; op: string }) => unknown }).startTransaction?.({\n\t\t\tname,\n\t\t\top: op || \"operation\",\n\t\t}) || null\n\t);\n}\n\n/**\n * Flush pending Sentry events\n * Call this before process exit in production\n */\nexport async function flushSentry(timeout = 2000): Promise<boolean> {\n\tif (process.env.DISABLE_SENTRY === \"true\" || !Sentry) {\n\t\treturn true;\n\t}\n\n\treturn await Sentry.close(timeout);\n}\n\n// Export wrapper functions only (not the full Sentry type to avoid DTS generation issues)\n// Applications should use the specific functions exported above\n// If direct Sentry access is needed: import * as Sentry from \"@sentry/node\"\n","import { logger } from \"../logging/logger\";\n\n// Error budget configuration\nconst ERROR_BUDGET = 0.01; // 1% error rate\nconst ALERT_THRESHOLD = 0.005; // 0.5% error rate (early warning)\n\n// Error metrics tracking\nconst errorMetrics = {\n\ttotalRequests: 0,\n\terrorCount: 0,\n\tlastAlertTime: 0,\n};\n\n// Record a successful request\nexport function recordSuccess() {\n\terrorMetrics.totalRequests++;\n}\n\n// Record an error\nexport function recordError() {\n\terrorMetrics.totalRequests++;\n\terrorMetrics.errorCount++;\n}\n\n// Calculate current error rate\nexport function getErrorRate() {\n\tif (errorMetrics.totalRequests === 0) {\n\t\treturn 0;\n\t}\n\treturn errorMetrics.errorCount / errorMetrics.totalRequests;\n}\n\nexport async function checkErrorBudget() {\n\tconst errorRate = getErrorRate();\n\n\t// Early warning alert\n\tif (errorRate > ALERT_THRESHOLD && Date.now() - errorMetrics.lastAlertTime > 60000) {\n\t\tlogger.warn(\n\t\t\t{\n\t\t\t\terrorRate: `${(errorRate * 100).toFixed(2)}%`,\n\t\t\t\tthreshold: `${(ALERT_THRESHOLD * 100).toFixed(2)}%`,\n\t\t\t\terrorCount: errorMetrics.errorCount,\n\t\t\t\ttotalRequests: errorMetrics.totalRequests,\n\t\t\t},\n\t\t\t\"Error rate approaching budget threshold\",\n\t\t);\n\n\t\terrorMetrics.lastAlertTime = Date.now();\n\t}\n\n\t// Budget exceeded alert\n\tif (errorRate > ERROR_BUDGET) {\n\t\tlogger.error(\n\t\t\t{\n\t\t\t\terrorRate: `${(errorRate * 100).toFixed(2)}%`,\n\t\t\t\tbudget: `${(ERROR_BUDGET * 100).toFixed(2)}%`,\n\t\t\t\terrorCount: errorMetrics.errorCount,\n\t\t\t\ttotalRequests: errorMetrics.totalRequests,\n\t\t\t\trecommendation: \"Investigate root cause immediately and consider rolling back\",\n\t\t\t},\n\t\t\t\"🚨 Error budget exceeded!\",\n\t\t);\n\n\t\t// In a real implementation, you would send alerts to Slack, email, etc.\n\t\tawait sendAlert({\n\t\t\tchannel: \"#alerts\",\n\t\t\tmessage: `🚨 Error budget exceeded! Current error rate: ${(errorRate * 100).toFixed(\n\t\t\t\t2,\n\t\t\t)}% (Budget: ${(ERROR_BUDGET * 100).toFixed(2)}%)`,\n\t\t});\n\t}\n}\n\n// Send alert to monitoring system\nasync function sendAlert(alert: { channel: string; message: string }) {\n\t// This would integrate with your alerting system (Slack, PagerDuty, etc.)\n\tlogger.info(alert, \"Alert sent\");\n\n\t// Example integration with a webhook\n\t/*\n try {\n await fetch(process.env.ALERT_WEBHOOK_URL!, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n channel: alert.channel,\n text: alert.message,\n }),\n });\n } catch (error) {\n logger.error({ error }, \"Failed to send alert\");\n }\n */\n}\n\n// Reset metrics (useful for testing)\nexport function resetMetrics() {\n\terrorMetrics.totalRequests = 0;\n\terrorMetrics.errorCount = 0;\n\terrorMetrics.lastAlertTime = 0;\n}\n\n// Get current metrics\nexport function getMetrics() {\n\treturn {\n\t\t...errorMetrics,\n\t\terrorRate: getErrorRate(),\n\t};\n}\n","/**\n * OpenTelemetry Implementation of InstrumentationProvider\n *\n * Production-ready instrumentation using OpenTelemetry SDK.\n * Supports distributed tracing, context propagation, metrics, and trace-log correlation.\n *\n * Key Features:\n * - Pino instrumentation for automatic trace_id/span_id injection into logs\n * - W3C TraceContext propagation for distributed tracing\n * - Configurable sampling rates\n * - OTLP exporter for Axiom/Grafana/Jaeger\n */\n\nimport type { Tracer } from \"@opentelemetry/api\";\nimport {\n\tcontext,\n\tmetrics,\n\ttype Context as OTelContext,\n\ttype Span as OTelSpan,\n\tSpanStatusCode as OTelSpanStatusCode,\n\tpropagation,\n\tROOT_CONTEXT,\n\ttrace,\n} from \"@opentelemetry/api\";\nimport { OTLPMetricExporter } from \"@opentelemetry/exporter-metrics-otlp-http\";\nimport { OTLPTraceExporter } from \"@opentelemetry/exporter-trace-otlp-http\";\nimport { PgInstrumentation } from \"@opentelemetry/instrumentation-pg\";\nimport { PinoInstrumentation } from \"@opentelemetry/instrumentation-pino\";\nimport { resourceFromAttributes } from \"@opentelemetry/resources\";\nimport { MeterProvider, PeriodicExportingMetricReader } from \"@opentelemetry/sdk-metrics\";\nimport {\n\tBatchSpanProcessor,\n\tConsoleSpanExporter,\n\ttype SpanProcessor,\n\tTraceIdRatioBasedSampler,\n} from \"@opentelemetry/sdk-trace-base\";\nimport { NodeTracerProvider } from \"@opentelemetry/sdk-trace-node\";\nimport { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } from \"@opentelemetry/semantic-conventions\";\nimport type {\n\tAttributes,\n\tContext,\n\tContextCarrier,\n\tInstrumentationProvider,\n\tSpan,\n\tSpanOptions,\n\tSpanStatusCode,\n} from \"@vreko/contracts\";\n\nexport interface OTelConfig {\n\t/** Service name (e.g., 'vreko-api', 'vreko-vscode') */\n\tserviceName: string;\n\t/** Service version */\n\tserviceVersion?: string;\n\t/** Environment (dev, staging, production) */\n\tenvironment?: string;\n\t/** OTLP collector URL (e.g., 'http://localhost:4318/v1/traces') */\n\tcollectorUrl?: string;\n\t/** Enable console exporter (for debugging) */\n\tenableConsole?: boolean;\n\t/** Sampling rate (0.0 - 1.0) */\n\tsampleRate?: number;\n}\n\n/**\n * OpenTelemetry Span Adapter\n * Wraps OTel span to match our Span interface\n */\nclass OTelSpanAdapter implements Span {\n\tconstructor(private otelSpan: OTelSpan) {\n\t\t/* intentionally empty */\n\t}\n\n\tsetAttribute(key: string, value: string | number | boolean): void {\n\t\tthis.otelSpan.setAttribute(key, value);\n\t}\n\n\tsetAttributes(attributes: Attributes): void {\n\t\tthis.otelSpan.setAttributes(attributes);\n\t}\n\n\taddEvent(name: string, attributes?: Attributes): void {\n\t\tthis.otelSpan.addEvent(name, attributes);\n\t}\n\n\tsetStatus(status: { code: SpanStatusCode; message?: string }): void {\n\t\tthis.otelSpan.setStatus({\n\t\t\tcode: status.code,\n\t\t\tmessage: status.message,\n\t\t});\n\t}\n\n\trecordException(error: Error): void {\n\t\tthis.otelSpan.recordException(error);\n\t}\n\n\tend(): void {\n\t\tthis.otelSpan.end();\n\t}\n\n\tisRecording(): boolean {\n\t\treturn this.otelSpan.isRecording();\n\t}\n}\n\n/**\n * OpenTelemetry Instrumentation Provider\n *\n * Implements the InstrumentationProvider interface with full OTel support.\n * Automatically injects trace context into Pino logs for seamless correlation.\n *\n * Note on Metrics (2026 Best Practice):\n * - Meter is initialized once and reused throughout application lifetime\n * - Metrics are no-ops until MeterProvider is registered at application startup\n * - To enable: Register MeterProvider with OTLP exporter in server initialization\n */\nexport class OTelInstrumentationProvider implements InstrumentationProvider {\n\tprivate tracer: Tracer;\n\tprivate provider: NodeTracerProvider;\n\tprivate meter: ReturnType<typeof metrics.getMeter>;\n\n\tconstructor(config: OTelConfig) {\n\t\t// Create resource with service metadata\n\t\tconst resource = resourceFromAttributes({\n\t\t\t[ATTR_SERVICE_NAME]: config.serviceName,\n\t\t\t[ATTR_SERVICE_VERSION]: config.serviceVersion || \"unknown\",\n\t\t\t\"deployment.environment\": config.environment || \"development\",\n\t\t\t\"service.instance.id\": process.pid.toString(),\n\t\t\t\"host.name\": process.env.HOSTNAME || \"unknown\",\n\t\t\t\"process.pid\": process.pid,\n\t\t});\n\n\t\t// Build span processors array (SDK 2.0 uses constructor option instead of addSpanProcessor)\n\t\tconst spanProcessors: SpanProcessor[] = [];\n\n\t\tif (config.collectorUrl) {\n\t\t\t// OTLP exporter for Axiom/Grafana/Jaeger\n\t\t\tconst otlpExporter = new OTLPTraceExporter({\n\t\t\t\turl: config.collectorUrl,\n\t\t\t});\n\t\t\tspanProcessors.push(new BatchSpanProcessor(otlpExporter));\n\t\t}\n\n\t\tif (config.enableConsole) {\n\t\t\t// Console exporter for debugging\n\t\t\tconst consoleExporter = new ConsoleSpanExporter();\n\t\t\tspanProcessors.push(new BatchSpanProcessor(consoleExporter));\n\t\t}\n\n\t\t// Initialize tracer provider with optional sampling\n\t\tconst samplingRate = config.sampleRate ?? 1.0;\n\t\tconst sampler = new TraceIdRatioBasedSampler(samplingRate);\n\n\t\tthis.provider = new NodeTracerProvider({\n\t\t\tresource,\n\t\t\tsampler,\n\t\t\tspanProcessors,\n\t\t});\n\n\t\t// Register provider globally\n\t\tthis.provider.register();\n\n\t\t// Register Pino instrumentation for trace-log correlation\n\t\t// This auto-injects trace_id, span_id, trace_flags into every Pino log\n\t\t// within an active span context\n\t\tconst pinoInstrumentation = new PinoInstrumentation({\n\t\t\t// Keep default log keys: trace_id, span_id, trace_flags\n\t\t\t// These match standard OTel semantic conventions\n\t\t\tdisableLogSending: true, // Don't send logs via OTLP (we use Axiom transport directly)\n\t\t\tdisableLogCorrelation: false, // Enable trace context injection\n\t\t});\n\n\t\t// Register PostgreSQL instrumentation for database query tracing\n\t\t// Captures all SQL queries executed through the pg driver\n\t\tconst pgInstrumentation = new PgInstrumentation({\n\t\t\t// Add database query attributes to spans\n\t\t\trequireParentSpan: false, // Allow spans without parent (standalone queries)\n\t\t\tenhancedDatabaseReporting: true, // Include additional database attributes\n\t\t});\n\n\t\t// Manually patch Pino and PostgreSQL since we're initializing after module imports\n\t\t// This is safe because instrumentations handle patching gracefully\n\t\ttry {\n\t\t\tpinoInstrumentation.enable();\n\t\t\tpgInstrumentation.enable();\n\t\t} catch {\n\t\t\t// Modules may already be loaded; instrumentations handle gracefully\n\t\t}\n\n\t\t// Get tracer instance\n\t\tthis.tracer = trace.getTracer(config.serviceName, config.serviceVersion);\n\n\t\t// Get meter instance - created once, reused throughout application lifetime\n\t\t// This follows 2026 OTel best practice: Meter is expensive and meant to be reused\n\t\tthis.meter = metrics.getMeter(config.serviceName, config.serviceVersion || \"unknown\");\n\n\t\t// Register MeterProvider with OTLP exporter for metrics\n\t\ttry {\n\t\t\tif (config.collectorUrl) {\n\t\t\t\tconst metricsUrl = config.collectorUrl.replace(\"/traces\", \"/metrics\");\n\t\t\t\tconst metricReader = new PeriodicExportingMetricReader({\n\t\t\t\t\texporter: new OTLPMetricExporter({ url: metricsUrl }),\n\t\t\t\t\texportIntervalMillis: 60000,\n\t\t\t\t});\n\n\t\t\t\tconst meterProvider = new MeterProvider({\n\t\t\t\t\tresource,\n\t\t\t\t\treaders: [metricReader],\n\t\t\t\t});\n\n\t\t\t\tmetrics.setGlobalMeterProvider(meterProvider);\n\t\t\t}\n\t\t} catch (_error) {}\n\t}\n\n\tstartSpan(name: string, options?: SpanOptions): Span {\n\t\tconst otelSpan = this.tracer.startSpan(name, {\n\t\t\tkind: options?.kind,\n\t\t\tattributes: options?.attributes,\n\t\t\tstartTime: options?.startTime,\n\t\t});\n\t\treturn new OTelSpanAdapter(otelSpan);\n\t}\n\n\tasync withSpan<T>(name: string, fn: (span: Span) => Promise<T>, options?: SpanOptions): Promise<T> {\n\t\t// Use parent context if provided, otherwise use active context\n\t\tconst parentCtx = options?.parent ? (options.parent as OTelContext) : context.active();\n\n\t\treturn await this.tracer.startActiveSpan(\n\t\t\tname,\n\t\t\t{\n\t\t\t\tkind: options?.kind,\n\t\t\t\tattributes: options?.attributes,\n\t\t\t\tstartTime: options?.startTime,\n\t\t\t},\n\t\t\tparentCtx, // Pass parent context here\n\t\t\tasync (otelSpan) => {\n\t\t\t\tconst span = new OTelSpanAdapter(otelSpan);\n\t\t\t\ttry {\n\t\t\t\t\tconst result = await fn(span);\n\t\t\t\t\totelSpan.setStatus({ code: OTelSpanStatusCode.OK });\n\t\t\t\t\treturn result;\n\t\t\t\t} catch (error) {\n\t\t\t\t\totelSpan.recordException(error as Error);\n\t\t\t\t\totelSpan.setStatus({\n\t\t\t\t\t\tcode: OTelSpanStatusCode.ERROR,\n\t\t\t\t\t\tmessage: error instanceof Error ? error.message : String(error),\n\t\t\t\t\t});\n\t\t\t\t\tthrow error;\n\t\t\t\t} finally {\n\t\t\t\t\totelSpan.end();\n\t\t\t\t}\n\t\t\t},\n\t\t);\n\t}\n\n\tinjectContext(carrier: ContextCarrier): void {\n\t\t// Inject current context into carrier (HTTP headers)\n\t\tpropagation.inject(context.active(), carrier);\n\t}\n\n\textractContext(carrier: ContextCarrier): Context | null {\n\t\t// Extract context from carrier using ROOT_CONTEXT as base to avoid pollution\n\t\tconst extractedContext = propagation.extract(ROOT_CONTEXT, carrier);\n\n\t\t// Check if context has trace information\n\t\tconst span = trace.getSpan(extractedContext);\n\t\tif (span?.spanContext().traceId) {\n\t\t\treturn extractedContext as unknown as Context;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\trecordMetric(name: string, value: number, attributes?: Attributes): void {\n\t\tconst counter = this.meter.createCounter(name);\n\t\tcounter.add(value, attributes);\n\t}\n\n\trecordEvent(_name: string, _attributes?: Attributes): void {\n\t\t// No-op implementation - standalone events not yet implemented\n\t\t// Most events should be added to active span via span.addEvent()\n\t\t// This method is available for future standalone event support if needed\n\t}\n\n\tasync shutdown(): Promise<void> {\n\t\tawait this.provider.shutdown();\n\t}\n}\n","import type { FeatureFlag } from \"@vreko/contracts\";\nimport { FEATURE_FLAGS, FeatureManager } from \"@vreko/contracts\";\nimport type { LegacyTelemetryEvent as TelemetryEvent } from \"@vreko/contracts/events\";\nimport { validateLegacyTelemetryEvent as validateTelemetryEvent } from \"@vreko/contracts/events\";\n\ninterface TelemetryEventInternal {\n\tevent: string;\n\tproperties?: Record<string, unknown>;\n\ttimestamp: number;\n}\n\nexport class TelemetryClient {\n\tprivate flags: Map<FeatureFlag, boolean> = new Map();\n\tprivate eventQueue: TelemetryEventInternal[] = [];\n\tprivate flushInterval = 5000; // 5 seconds\n\tprivate maxQueueSize = 100;\n\tprivate rateLimitWindow = 60000; // 1 minute\n\tprivate eventCounts: Map<string, number> = new Map();\n\tprivate lastRateLimitReset: number = Date.now();\n\tprivate proxyUrl: string;\n\tprivate offlineMode = false;\n\tprivate anonymousId: string; // Stored for consistent clientId across flag calls\n\n\tconstructor(\n\t\t_apiKey: string,\n\t\tproxyHost: string,\n\t\tprivate environment: \"vscode\" | \"mcp\" | \"cli\",\n\t) {\n\t\tthis.proxyUrl = `${proxyHost}/api/telemetry/events`;\n\t\t// DO NOT initialize PostHog SDK with direct host\n\t\t// Instead, implement custom transport layer\n\n\t\t// Generate and store anonymous ID for this client instance\n\t\t// Stored once at construction time to ensure stable clientId (2026 best practice)\n\t\tthis.anonymousId = this.generateAnonymousId();\n\n\t\t// Start periodic flush\n\t\tsetInterval(() => this.flush(), this.flushInterval);\n\t}\n\n\tasync initialize() {\n\t\t/* intentionally empty */\n\t}\n\n\t/**\n\t * Set offline mode\n\t * @param enabled Whether offline mode is enabled\n\t */\n\tsetOfflineMode(enabled: boolean): void {\n\t\tthis.offlineMode = enabled;\n\t}\n\n\t/**\n\t * Check if offline mode is enabled\n\t * @returns Whether offline mode is enabled\n\t */\n\tisOfflineMode(): boolean {\n\t\treturn this.offlineMode;\n\t}\n\n\tisEnabled(flag: FeatureFlag): boolean {\n\t\t// Local cache with fallback to defaults\n\t\tconst value = this.flags.get(flag) ?? FEATURE_FLAGS[flag];\n\t\treturn Boolean(value);\n\t}\n\n\tasync reloadFlags() {\n\t\t/* intentionally empty */\n\t}\n\n\t/**\n\t * Track a telemetry event with strict typing and validation\n\t * @param event The event name (must be from the whitelist)\n\t * @param properties The event properties (validated at runtime)\n\t */\n\ttrackEvent(event: TelemetryEvent): void {\n\t\t// Validate the event at runtime\n\t\tif (!validateTelemetryEvent(event)) {\n\t\t\tconsole.warn(\"Invalid telemetry event, skipping:\", event);\n\t\t\treturn;\n\t\t}\n\n\t\t// If offline mode is enabled, skip tracking\n\t\tif (this.offlineMode) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst featureManager = FeatureManager.getInstance();\n\n\t\t// Check if telemetry is enabled\n\t\tif (!featureManager.isEnabled(\"telemetry.detailed_events\")) {\n\t\t\t// Only track minimal events\n\t\t\tif (![\"checkpoint.created\", \"risk.high\", \"error\"].includes(event.event)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\t// Apply sampling rate\n\t\tconst samplingRate = featureManager.getValue<number>(\"telemetry.sampling_rate\") ?? 1.0;\n\t\tif (Math.random() > samplingRate) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Rate limiting\n\t\tif (this.isRateLimited(event.event)) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Add to queue\n\t\tthis.eventQueue.push({\n\t\t\tevent: event.event,\n\t\t\tproperties: {\n\t\t\t\t...this.sanitizeProperties(event.properties || {}),\n\t\t\t\tenvironment: this.environment,\n\t\t\t\ttimestamp: event.timestamp,\n\t\t\t},\n\t\t\ttimestamp: event.timestamp,\n\t\t});\n\n\t\t// Flush if queue is full\n\t\tif (this.eventQueue.length >= this.maxQueueSize) {\n\t\t\tthis.flush();\n\t\t}\n\t}\n\n\t/**\n\t * Track a telemetry event with string-based event name (legacy compatibility)\n\t * @param event The event name\n\t * @param properties The event properties\n\t */\n\ttrack(event: string, properties?: Record<string, unknown>) {\n\t\t// Convert to typed event for validation\n\t\tconst typedEvent: TelemetryEvent = {\n\t\t\tevent,\n\t\t\tproperties,\n\t\t\ttimestamp: Date.now(),\n\t\t};\n\n\t\tthis.trackEvent(typedEvent);\n\t}\n\n\tprivate isRateLimited(event: string): boolean {\n\t\tconst now = Date.now();\n\n\t\t// Reset rate limit counters every minute\n\t\tif (now - this.lastRateLimitReset > this.rateLimitWindow) {\n\t\t\tthis.eventCounts.clear();\n\t\t\tthis.lastRateLimitReset = now;\n\t\t}\n\n\t\t// Check event count for this event type\n\t\tconst count = this.eventCounts.get(event) || 0;\n\t\tconst maxEventsPerWindow = 10; // Max 10 events per minute per event type\n\n\t\tif (count >= maxEventsPerWindow) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Increment counter\n\t\tthis.eventCounts.set(event, count + 1);\n\t\treturn false;\n\t}\n\n\t/**\n\t * Sanitize properties to remove PII before sending\n\t */\n\tprivate sanitizeProperties(properties?: Record<string, unknown>): Record<string, unknown> {\n\t\tconst sanitized: Record<string, unknown> = {};\n\n\t\tif (!properties) {\n\t\t\treturn sanitized;\n\t\t}\n\n\t\t// Allowlist of safe properties\n\t\tconst allowedProps = [\n\t\t\t\"version\",\n\t\t\t\"platform\",\n\t\t\t\"duration\",\n\t\t\t\"success\",\n\t\t\t\"filesCount\",\n\t\t\t\"method\",\n\t\t\t\"trigger\",\n\t\t\t\"feature\",\n\t\t\t\"viewId\",\n\t\t\t\"command\",\n\t\t];\n\n\t\tfor (const key of allowedProps) {\n\t\t\tif (key in properties) {\n\t\t\t\tsanitized[key] = properties[key];\n\t\t\t}\n\t\t}\n\n\t\treturn sanitized;\n\t}\n\n\t/**\n\t * Get the anonymous ID for this client instance\n\t * @returns The stored anonymous ID\n\t */\n\tgetAnonymousId(): string {\n\t\treturn this.anonymousId;\n\t}\n\n\tprivate generateAnonymousId(): string {\n\t\t// Simple implementation - in real app would use machine ID\n\t\treturn `${this.environment}_${Math.random().toString(36).substr(2, 9)}`;\n\t}\n\n\t/**\n\t * Get current package version\n\t * @returns The current version string\n\t */\n\tprivate getVersion(): string {\n\t\ttry {\n\t\t\t// Try to get version from package.json\n\t\t\tconst packageJson = require(\"../../package.json\");\n\t\t\treturn packageJson.version || \"unknown\";\n\t\t} catch (_error) {\n\t\t\t// Fallback to environment variable or default\n\t\t\treturn process.env.VREKO_VERSION || \"1.0.0\";\n\t\t}\n\t}\n\n\t/**\n\t * Custom transport layer - routes all events through proxy\n\t */\n\tprivate async customTransport(batch: TelemetryEventInternal[]): Promise<void> {\n\t\t// If offline mode is enabled, skip network requests\n\t\tif (this.offlineMode) {\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tconst response = await fetch(this.proxyUrl, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\t\"X-Vreko-Platform\": this.environment,\n\t\t\t\t\t\"X-Vreko-Version\": this.getVersion(),\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\tevents: batch.map((event) => ({\n\t\t\t\t\t\tevent: event.event,\n\t\t\t\t\t\tproperties: this.sanitizeProperties(event.properties || {}),\n\t\t\t\t\t\ttimestamp: event.timestamp,\n\t\t\t\t\t})),\n\t\t\t\t}),\n\t\t\t});\n\n\t\t\tif (!response.ok) {\n\t\t\t\tconst _error = await response.text();\n\t\t\t}\n\t\t} catch (_error) {\n\t\t\t// Fail silently - never block user operations for telemetry\n\t\t}\n\t}\n\n\tprivate async flush() {\n\t\t// If offline mode is enabled, skip flushing\n\t\tif (this.offlineMode) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.eventQueue.length === 0) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst eventsToFlush = [...this.eventQueue];\n\t\tthis.eventQueue = [];\n\n\t\ttry {\n\t\t\t// Use custom transport instead of direct PostHog connection\n\t\t\tawait this.customTransport(eventsToFlush);\n\t\t} catch (_error) {\n\t\t\t// Re-add events to queue for retry\n\t\t\tthis.eventQueue.unshift(...eventsToFlush);\n\t\t}\n\t}\n}\n"]}