e11y 0.2.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (288) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +130 -10
  3. data/CHANGELOG.md +80 -1
  4. data/CLAUDE.md +168 -0
  5. data/CONTRIBUTING.md +640 -0
  6. data/README.md +165 -701
  7. data/RELEASE.md +41 -12
  8. data/Rakefile +249 -57
  9. data/config/README.md +1 -1
  10. data/config/loki-local-config.yaml +12 -0
  11. data/config/otel-collector-config.yaml +44 -0
  12. data/cucumber.yml +1 -0
  13. data/docker-compose.yml +18 -2
  14. data/docs/ADAPTERS.md +76 -0
  15. data/docs/ADAPTIVE_SAMPLING.md +59 -0
  16. data/docs/COMPARISON.md +104 -0
  17. data/docs/CONFIGURATION.md +52 -0
  18. data/docs/DISTRIBUTED_TRACING.md +44 -0
  19. data/docs/LIMITATIONS.md +13 -0
  20. data/docs/METRICS_DSL.md +84 -0
  21. data/docs/PERFORMANCE.md +60 -0
  22. data/docs/PII_FILTERING.md +40 -0
  23. data/docs/PRESETS.md +65 -0
  24. data/docs/QUICK-START.md +546 -587
  25. data/docs/RAILS_INTEGRATION.md +79 -0
  26. data/docs/SCHEMA_VALIDATION.md +63 -0
  27. data/docs/SLO-PROMQL-ALERTS.md +161 -0
  28. data/docs/TESTING.md +69 -0
  29. data/docs/{ADR-001-architecture.md → architecture/ADR-001-architecture.md} +36 -65
  30. data/docs/{ADR-002-metrics-yabeda.md → architecture/ADR-002-metrics-yabeda.md} +62 -236
  31. data/docs/architecture/ADR-003-slo-observability.md +1402 -0
  32. data/docs/{ADR-004-adapter-architecture.md → architecture/ADR-004-adapter-architecture.md} +163 -146
  33. data/docs/{ADR-005-tracing-context.md → architecture/ADR-005-tracing-context.md} +10 -9
  34. data/docs/{ADR-006-security-compliance.md → architecture/ADR-006-security-compliance.md} +184 -191
  35. data/docs/{ADR-007-opentelemetry-integration.md → architecture/ADR-007-opentelemetry-integration.md} +3 -21
  36. data/docs/{ADR-008-rails-integration.md → architecture/ADR-008-rails-integration.md} +182 -743
  37. data/docs/{ADR-009-cost-optimization.md → architecture/ADR-009-cost-optimization.md} +45 -54
  38. data/docs/architecture/ADR-010-developer-experience.md +522 -0
  39. data/docs/{ADR-011-testing-strategy.md → architecture/ADR-011-testing-strategy.md} +44 -86
  40. data/docs/{ADR-012-event-evolution.md → architecture/ADR-012-event-evolution.md} +11 -11
  41. data/docs/{ADR-013-reliability-error-handling.md → architecture/ADR-013-reliability-error-handling.md} +37 -12
  42. data/docs/{ADR-014-event-driven-slo.md → architecture/ADR-014-event-driven-slo.md} +12 -24
  43. data/docs/{ADR-015-middleware-order.md → architecture/ADR-015-middleware-order.md} +43 -59
  44. data/docs/{ADR-016-self-monitoring-slo.md → architecture/ADR-016-self-monitoring-slo.md} +58 -355
  45. data/docs/{ADR-017-multi-rails-compatibility.md → architecture/ADR-017-multi-rails-compatibility.md} +4 -11
  46. data/docs/architecture/ADR-018-memory-optimization.md +366 -0
  47. data/docs/{ADR-INDEX.md → architecture/ADR-INDEX.md} +11 -6
  48. data/docs/plans/2026-03-20-browser-overlay-svelte.md +281 -0
  49. data/docs/{00-ICP-AND-TIMELINE.md → prd/00-ICP-AND-TIMELINE.md} +6 -6
  50. data/docs/{01-SCALE-REQUIREMENTS.md → prd/01-SCALE-REQUIREMENTS.md} +6 -6
  51. data/docs/prd/01-overview-vision.md +19 -14
  52. data/docs/use_cases/README.md +22 -23
  53. data/docs/use_cases/UC-001-request-scoped-debug-buffering.md +50 -44
  54. data/docs/use_cases/UC-002-business-event-tracking.md +26 -95
  55. data/docs/use_cases/UC-003-event-metrics.md +66 -0
  56. data/docs/use_cases/UC-004-zero-config-slo-tracking.md +33 -684
  57. data/docs/use_cases/UC-005-sentry-integration.md +13 -15
  58. data/docs/use_cases/UC-006-trace-context-management.md +30 -28
  59. data/docs/use_cases/UC-007-pii-filtering.md +35 -87
  60. data/docs/use_cases/UC-008-opentelemetry-integration.md +51 -89
  61. data/docs/use_cases/UC-009-multi-service-tracing.md +30 -178
  62. data/docs/use_cases/UC-010-background-job-tracking.md +24 -91
  63. data/docs/use_cases/UC-011-rate-limiting.md +95 -168
  64. data/docs/use_cases/UC-012-audit-trail.md +21 -46
  65. data/docs/use_cases/UC-013-high-cardinality-protection.md +29 -167
  66. data/docs/use_cases/UC-014-adaptive-sampling.md +2 -2
  67. data/docs/use_cases/UC-015-cost-optimization.md +46 -99
  68. data/docs/use_cases/UC-016-rails-logger-migration.md +39 -213
  69. data/docs/use_cases/UC-017-local-development.md +203 -777
  70. data/docs/use_cases/UC-018-testing-events.md +3 -3
  71. data/docs/use_cases/UC-019-retention-based-routing.md +53 -106
  72. data/docs/use_cases/UC-020-event-versioning.md +8 -9
  73. data/docs/use_cases/UC-021-error-handling-retry-dlq.md +18 -22
  74. data/docs/use_cases/UC-022-event-registry.md +15 -21
  75. data/docs/use_cases/backlog.md +119 -87
  76. data/e11y.gemspec +2 -2
  77. data/gems/e11y-devtools/README.md +158 -0
  78. data/gems/e11y-devtools/config/routes.rb +15 -0
  79. data/gems/e11y-devtools/e11y-devtools.gemspec +25 -0
  80. data/gems/e11y-devtools/exe/e11y +34 -0
  81. data/gems/e11y-devtools/frontend/.gitignore +24 -0
  82. data/gems/e11y-devtools/frontend/README.md +51 -0
  83. data/gems/e11y-devtools/frontend/index.html +14 -0
  84. data/gems/e11y-devtools/frontend/package-lock.json +3707 -0
  85. data/gems/e11y-devtools/frontend/package.json +28 -0
  86. data/gems/e11y-devtools/frontend/public/mocks/v1/events/recent.json +4205 -0
  87. data/gems/e11y-devtools/frontend/public/mocks/v1/interactions.json +194 -0
  88. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/0a2e04027cfa22d014bc22e8b27cd913/events.json +86 -0
  89. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/0e1543af6a630fb3af6b52283154b3e0/events.json +169 -0
  90. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/1838b691faa49564f97db8592ff3978d/events.json +78 -0
  91. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/29f198f6588dacffb687777eb5f8f118/events.json +197 -0
  92. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/34bc3c9c0097de28a7a6f99b90a8e7bc/events.json +194 -0
  93. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/3ba6c20d068ab9cee00e51b180e66444/events.json +184 -0
  94. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/435bfd8f17b9009146a79812d7c3726d/events.json +144 -0
  95. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/4c7676e3fe668e99edb2b94d7d5678a9/events.json +222 -0
  96. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/6daf0d47974bedfc55d5de7004a3ea9f/events.json +194 -0
  97. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/8a81ada42834d15f287bb40010043605/events.json +194 -0
  98. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/8c0a98900edaae105469df8daedccf02/events.json +198 -0
  99. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/8e4f645180f8a7d1dce426b07380466b/events.json +222 -0
  100. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/93db346fa5d44a032605a13b627f4b80/events.json +128 -0
  101. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/98ff6146faf7bd9be8bd03a8275817ba/events.json +223 -0
  102. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/9997ddd0247bc7e25f2ca7a5c415c93d/events.json +197 -0
  103. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/99e35f8ef3baedd798cc4fd085980ad9/events.json +194 -0
  104. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/b4f3095c1909924cbc98889a86c83d6d/events.json +131 -0
  105. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/b54b7fc32b7575a7110de809d11ccda0/events.json +128 -0
  106. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/c0b48033fa06746bcc5886745e053cff/events.json +169 -0
  107. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/c44649ac76701b4558927cd2305ab535/events.json +169 -0
  108. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/d601ae3320057580a39dbdac2edfdf4a/events.json +248 -0
  109. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/e67e724bab422d2b52eeb49635e512e1/events.json +194 -0
  110. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/e6c72765a28f158a8485b35fa63f73da/events.json +194 -0
  111. data/gems/e11y-devtools/frontend/public/mocks/v1/traces/f541b87405c9a54819b18ebe529f6419/events.json +194 -0
  112. data/gems/e11y-devtools/frontend/scripts/generate_mocks.rb +397 -0
  113. data/gems/e11y-devtools/frontend/src/App.svelte +827 -0
  114. data/gems/e11y-devtools/frontend/src/components/Fab.svelte +19 -0
  115. data/gems/e11y-devtools/frontend/src/components/FilterBar.svelte +38 -0
  116. data/gems/e11y-devtools/frontend/src/components/FullscreenPanel.svelte +82 -0
  117. data/gems/e11y-devtools/frontend/src/components/InteractionsTimeline.svelte +264 -0
  118. data/gems/e11y-devtools/frontend/src/components/RecentHistogram.svelte +354 -0
  119. data/gems/e11y-devtools/frontend/src/lib/api.ts +37 -0
  120. data/gems/e11y-devtools/frontend/src/lib/eventIdentity.ts +12 -0
  121. data/gems/e11y-devtools/frontend/src/lib/format.ts +37 -0
  122. data/gems/e11y-devtools/frontend/src/lib/listFilter.ts +43 -0
  123. data/gems/e11y-devtools/frontend/src/lib/recentVolume.ts +80 -0
  124. data/gems/e11y-devtools/frontend/src/lib/router.ts +12 -0
  125. data/gems/e11y-devtools/frontend/src/lib/transitions.ts +34 -0
  126. data/gems/e11y-devtools/frontend/src/lib/viewportOrigin.ts +25 -0
  127. data/gems/e11y-devtools/frontend/src/main.ts +8 -0
  128. data/gems/e11y-devtools/frontend/src/overlay-entry.ts +24 -0
  129. data/gems/e11y-devtools/frontend/src/overlay.css +1080 -0
  130. data/gems/e11y-devtools/frontend/svelte.config.js +2 -0
  131. data/gems/e11y-devtools/frontend/test_puppeteer.js +41 -0
  132. data/gems/e11y-devtools/frontend/test_scale.js +3 -0
  133. data/gems/e11y-devtools/frontend/tsconfig.app.json +21 -0
  134. data/gems/e11y-devtools/frontend/tsconfig.json +7 -0
  135. data/gems/e11y-devtools/frontend/tsconfig.node.json +26 -0
  136. data/gems/e11y-devtools/frontend/vite.config.ts +36 -0
  137. data/gems/e11y-devtools/lib/e11y/devtools/mcp/server.rb +96 -0
  138. data/gems/e11y-devtools/lib/e11y/devtools/mcp/tool_base.rb +25 -0
  139. data/gems/e11y-devtools/lib/e11y/devtools/mcp/tools/clear.rb +31 -0
  140. data/gems/e11y-devtools/lib/e11y/devtools/mcp/tools/errors.rb +35 -0
  141. data/gems/e11y-devtools/lib/e11y/devtools/mcp/tools/event_detail.rb +33 -0
  142. data/gems/e11y-devtools/lib/e11y/devtools/mcp/tools/events_by_trace.rb +33 -0
  143. data/gems/e11y-devtools/lib/e11y/devtools/mcp/tools/interactions.rb +40 -0
  144. data/gems/e11y-devtools/lib/e11y/devtools/mcp/tools/recent_events.rb +34 -0
  145. data/gems/e11y-devtools/lib/e11y/devtools/mcp/tools/search.rb +34 -0
  146. data/gems/e11y-devtools/lib/e11y/devtools/mcp/tools/stats.rb +30 -0
  147. data/gems/e11y-devtools/lib/e11y/devtools/overlay/assets/overlay.js +20 -0
  148. data/gems/e11y-devtools/lib/e11y/devtools/overlay/controller.rb +94 -0
  149. data/gems/e11y-devtools/lib/e11y/devtools/overlay/engine.rb +26 -0
  150. data/gems/e11y-devtools/lib/e11y/devtools/overlay/middleware.rb +80 -0
  151. data/gems/e11y-devtools/lib/e11y/devtools/overlay/rails_controller.rb +67 -0
  152. data/gems/e11y-devtools/lib/e11y/devtools/tui/app.rb +262 -0
  153. data/gems/e11y-devtools/lib/e11y/devtools/tui/grouping.rb +66 -0
  154. data/gems/e11y-devtools/lib/e11y/devtools/tui/widgets/event_detail.rb +62 -0
  155. data/gems/e11y-devtools/lib/e11y/devtools/tui/widgets/event_list.rb +70 -0
  156. data/gems/e11y-devtools/lib/e11y/devtools/tui/widgets/interaction_list.rb +47 -0
  157. data/gems/e11y-devtools/lib/e11y/devtools/version.rb +8 -0
  158. data/gems/e11y-devtools/lib/e11y/devtools.rb +13 -0
  159. data/gems/e11y-devtools/spec/e11y/devtools/mcp/tools_spec.rb +107 -0
  160. data/gems/e11y-devtools/spec/e11y/devtools/overlay/controller_spec.rb +91 -0
  161. data/gems/e11y-devtools/spec/e11y/devtools/overlay/middleware_spec.rb +46 -0
  162. data/gems/e11y-devtools/spec/e11y/devtools/tui/app_spec.rb +85 -0
  163. data/gems/e11y-devtools/spec/e11y/devtools/tui/grouping_spec.rb +64 -0
  164. data/gems/e11y-devtools/spec/spec_helper.rb +5 -0
  165. data/gems/e11y-devtools/spec/tui/widgets/event_list_spec.rb +44 -0
  166. data/gems/e11y-devtools/spec/tui/widgets/interaction_list_spec.rb +62 -0
  167. data/lib/e11y/adapters/audit_encrypted.rb +53 -11
  168. data/lib/e11y/adapters/base.rb +33 -34
  169. data/lib/e11y/adapters/dev_log/file_store.rb +143 -0
  170. data/lib/e11y/adapters/dev_log/query.rb +219 -0
  171. data/lib/e11y/adapters/dev_log.rb +118 -0
  172. data/lib/e11y/adapters/file.rb +3 -6
  173. data/lib/e11y/adapters/in_memory.rb +52 -5
  174. data/lib/e11y/adapters/in_memory_test.rb +29 -0
  175. data/lib/e11y/adapters/loki.rb +58 -23
  176. data/lib/e11y/adapters/null.rb +82 -0
  177. data/lib/e11y/adapters/opentelemetry_collector.rb +183 -0
  178. data/lib/e11y/adapters/otel_logs.rb +136 -23
  179. data/lib/e11y/adapters/sentry.rb +4 -7
  180. data/lib/e11y/adapters/stdout.rb +73 -7
  181. data/lib/e11y/adapters/yabeda.rb +153 -29
  182. data/lib/e11y/buffers/adaptive_buffer.rb +3 -17
  183. data/lib/e11y/buffers/{request_scoped_buffer.rb → ephemeral_buffer.rb} +72 -58
  184. data/lib/e11y/buffers/ring_buffer.rb +3 -16
  185. data/lib/e11y/configuration.rb +272 -0
  186. data/lib/e11y/console.rb +10 -17
  187. data/lib/e11y/current.rb +53 -1
  188. data/lib/e11y/debug/pipeline_inspector.rb +96 -0
  189. data/lib/e11y/documentation/generator.rb +48 -0
  190. data/lib/e11y/event/base.rb +176 -82
  191. data/lib/e11y/event/value_sampling_config.rb +1 -5
  192. data/lib/e11y/events/rails/database/query.rb +1 -4
  193. data/lib/e11y/events/rails/job/failed.rb +2 -0
  194. data/lib/e11y/instruments/active_job.rb +44 -12
  195. data/lib/e11y/instruments/rails_instrumentation.rb +49 -24
  196. data/lib/e11y/instruments/sidekiq.rb +135 -31
  197. data/lib/e11y/linters/base.rb +11 -0
  198. data/lib/e11y/linters/pii/pii_declaration_linter.rb +120 -0
  199. data/lib/e11y/linters/slo/config_consistency_linter.rb +76 -0
  200. data/lib/e11y/linters/slo/explicit_declaration_linter.rb +36 -0
  201. data/lib/e11y/linters/slo/slo_status_from_linter.rb +41 -0
  202. data/lib/e11y/logger/bridge.rb +26 -7
  203. data/lib/e11y/metrics/cardinality_protection.rb +10 -15
  204. data/lib/e11y/metrics/cardinality_tracker.rb +16 -6
  205. data/lib/e11y/metrics/registry.rb +3 -5
  206. data/lib/e11y/metrics/test_backend.rb +62 -0
  207. data/lib/e11y/metrics.rb +56 -10
  208. data/lib/e11y/middleware/adapter_resolver.rb +40 -0
  209. data/lib/e11y/middleware/audit_signing.rb +43 -6
  210. data/lib/e11y/middleware/baggage_protection.rb +75 -0
  211. data/lib/e11y/middleware/dev_log_source.rb +24 -0
  212. data/lib/e11y/middleware/event_slo.rb +23 -9
  213. data/lib/e11y/middleware/otel_span.rb +23 -0
  214. data/lib/e11y/middleware/pii_filter.rb +104 -75
  215. data/lib/e11y/middleware/rate_limiting.rb +54 -27
  216. data/lib/e11y/middleware/request.rb +70 -23
  217. data/lib/e11y/middleware/routing.rb +78 -21
  218. data/lib/e11y/middleware/sampling.rb +66 -17
  219. data/lib/e11y/middleware/self_monitoring_emit.rb +39 -0
  220. data/lib/e11y/middleware/trace_context.rb +45 -10
  221. data/lib/e11y/middleware/track_latency.rb +34 -0
  222. data/lib/e11y/middleware/validation.rb +7 -16
  223. data/lib/e11y/middleware/versioning.rb +26 -22
  224. data/lib/e11y/opentelemetry/semantic_conventions.rb +109 -0
  225. data/lib/e11y/opentelemetry/span_creator.rb +142 -0
  226. data/lib/e11y/pii/patterns.rb +12 -1
  227. data/lib/e11y/pipeline/builder.rb +4 -4
  228. data/lib/e11y/presets/audit_event.rb +13 -2
  229. data/lib/e11y/railtie.rb +52 -14
  230. data/lib/e11y/registry.rb +306 -0
  231. data/lib/e11y/reliability/circuit_breaker.rb +19 -21
  232. data/lib/e11y/reliability/dlq/base.rb +71 -0
  233. data/lib/e11y/reliability/dlq/file_adapter.rb +301 -0
  234. data/lib/e11y/reliability/dlq/file_storage.rb +63 -34
  235. data/lib/e11y/reliability/dlq/filter.rb +37 -54
  236. data/lib/e11y/reliability/retry_handler.rb +26 -29
  237. data/lib/e11y/reliability/retry_rate_limiter.rb +3 -11
  238. data/lib/e11y/sampling/error_spike_detector.rb +0 -2
  239. data/lib/e11y/sampling/load_monitor.rb +5 -9
  240. data/lib/e11y/sampling/stratified_tracker.rb +18 -0
  241. data/lib/e11y/self_monitoring/buffer_monitor.rb +2 -0
  242. data/lib/e11y/self_monitoring/performance_monitor.rb +19 -61
  243. data/lib/e11y/self_monitoring/reliability_monitor.rb +4 -74
  244. data/lib/e11y/slo/config_loader.rb +40 -0
  245. data/lib/e11y/slo/config_validator.rb +58 -0
  246. data/lib/e11y/slo/dashboard_generator.rb +122 -0
  247. data/lib/e11y/slo/event_driven.rb +8 -0
  248. data/lib/e11y/slo/tracker.rb +31 -4
  249. data/lib/e11y/testing/have_tracked_event_matcher.rb +190 -0
  250. data/lib/e11y/testing/rspec_matchers.rb +21 -0
  251. data/lib/e11y/testing/snapshot_matcher.rb +86 -0
  252. data/lib/e11y/trace_context/sampler.rb +35 -0
  253. data/lib/e11y/tracing/faraday_middleware.rb +31 -0
  254. data/lib/e11y/tracing/net_http_patch.rb +33 -0
  255. data/lib/e11y/tracing/propagator.rb +144 -0
  256. data/lib/e11y/tracing.rb +47 -0
  257. data/lib/e11y/version.rb +1 -1
  258. data/lib/e11y/versioning/version_extractor.rb +32 -0
  259. data/lib/e11y.rb +123 -266
  260. data/lib/generators/e11y/event/event_generator.rb +22 -0
  261. data/lib/generators/e11y/event/templates/event.rb.tt +16 -0
  262. data/lib/generators/e11y/grafana_dashboard/grafana_dashboard_generator.rb +30 -0
  263. data/lib/generators/e11y/grafana_dashboard/templates/e11y_dashboard.json +81 -0
  264. data/lib/generators/e11y/install/install_generator.rb +34 -0
  265. data/lib/generators/e11y/install/templates/e11y.rb +239 -0
  266. data/lib/generators/e11y/prometheus_alerts/prometheus_alerts_generator.rb +29 -0
  267. data/lib/generators/e11y/prometheus_alerts/templates/e11y_alerts.yml +28 -0
  268. data/lib/tasks/e11y_docs.rake +30 -0
  269. data/lib/tasks/e11y_events.rake +71 -0
  270. data/lib/tasks/e11y_lint.rake +91 -0
  271. data/lib/tasks/e11y_slo.rake +29 -0
  272. metadata +186 -39
  273. data/docs/ADR-003-slo-observability.md +0 -3337
  274. data/docs/ADR-010-developer-experience.md +0 -2166
  275. data/docs/API-REFERENCE-L28.md +0 -914
  276. data/docs/COMPREHENSIVE-CONFIGURATION.md +0 -2366
  277. data/docs/CONTRIBUTING.md +0 -312
  278. data/docs/IMPLEMENTATION_NOTES.md +0 -2804
  279. data/docs/IMPLEMENTATION_PLAN.md +0 -1971
  280. data/docs/IMPLEMENTATION_PLAN_ARCHITECTURE.md +0 -586
  281. data/docs/PLAN.md +0 -148
  282. data/docs/README.md +0 -296
  283. data/docs/design/00-memory-optimization.md +0 -593
  284. data/docs/guides/MIGRATION-L27-L28.md +0 -692
  285. data/docs/guides/PERFORMANCE-BENCHMARKS.md +0 -434
  286. data/docs/guides/README.md +0 -44
  287. data/docs/use_cases/UC-003-pattern-based-metrics.md +0 -1627
  288. data/lib/e11y/adapters/registry.rb +0 -141
@@ -39,7 +39,7 @@
39
39
  - High cardinality costs (Datadog, New Relic bills exploding)
40
40
 
41
41
  **What They Need:**
42
- - ✅ Pattern-based metrics (reduce boilerplate)
42
+ - ✅ Event-level metrics DSL (reduce boilerplate)
43
43
  - ✅ Cardinality protection (prevent cost explosions)
44
44
  - ✅ Multi-adapter support (integrate with existing stack)
45
45
  - ✅ Team-wide conventions (event schemas, PII filtering)
@@ -135,10 +135,10 @@
135
135
 
136
136
  ### Phase 2: Yabeda Integration (Weeks 9-12)
137
137
  **Target:** April 2025
138
- **Goal:** Pattern-based metrics automation
138
+ **Goal:** Event-level metrics automation
139
139
 
140
- **Week 9-10: Pattern Engine**
141
- - [ ] Pattern matching (`*`, `order.*`, `*.paid`)
140
+ **Week 9-10: Metrics DSL**
141
+ - [ ] Event-level `metrics do ... end` DSL
142
142
  - [ ] Label extraction from events
143
143
  - [ ] Counter metrics
144
144
  - [ ] Histogram metrics (with buckets)
@@ -261,7 +261,7 @@
261
261
  **Focus:** Feature-complete release candidate
262
262
 
263
263
  **New Features:**
264
- - ✅ Pattern-based metrics (Yabeda)
264
+ - ✅ Event-level metrics (Yabeda)
265
265
  - ✅ Cardinality protection
266
266
  - ✅ SLO tracking (zero-config)
267
267
  - ✅ OpenTelemetry integration
@@ -424,7 +424,7 @@
424
424
  - ✅ Rails-first design (vs OTel's language-agnostic complexity)
425
425
  - ✅ Zero-config SLO tracking (unique feature)
426
426
  - ✅ Request-scoped debug buffering (unique feature)
427
- - ✅ Pattern-based metrics (less boilerplate)
427
+ - ✅ Event-level metrics DSL (less boilerplate)
428
428
  - ✅ Cost optimization built-in (vs expensive SaaS)
429
429
 
430
430
  ---
@@ -66,11 +66,11 @@ E11y.configure do |config|
66
66
  worker_threads 2 # Multiple workers
67
67
  end
68
68
 
69
- # Adaptive sampling для cost control
69
+ # Adaptive sampling for cost control
70
70
  config.sampling do
71
71
  strategy :adaptive
72
72
  target_samples_per_second 200 # Cap at 200/sec
73
- min_rate 0.1 # Minimum 10% даже при высокой нагрузке
73
+ min_rate 0.1 # Minimum 10% even under high load
74
74
  end
75
75
  end
76
76
  ```
@@ -112,13 +112,13 @@ E11y.configure do |config|
112
112
  worker_threads 4 # Multiple workers
113
113
  end
114
114
 
115
- # Агрессивный sampling
115
+ # Aggressive sampling
116
116
  config.sampling do
117
117
  strategy :adaptive
118
118
  target_samples_per_second 1_000 # Cap at 1k/sec
119
- min_rate 0.01 # 1% минимум
119
+ min_rate 0.01 # 1% minimum
120
120
 
121
- # Tail-based sampling для критичных событий
121
+ # Tail-based sampling for critical events
122
122
  tail do
123
123
  enabled true
124
124
  sample_if do |events|
@@ -481,7 +481,7 @@ E11y.configure do |config|
481
481
  target_samples_per_second 1_000
482
482
  min_rate 0.01 # 1% minimum
483
483
 
484
- # Tail-based sampling для критичных событий
484
+ # Tail-based sampling for critical events
485
485
  tail do
486
486
  enabled true
487
487
  sample_if do |events|
@@ -9,15 +9,15 @@
9
9
 
10
10
  ## 📋 Executive Summary
11
11
 
12
- **E11y** (easy telemetry) - production-ready Ruby gem для структурированных бизнес-событий с уникальными killer features:
12
+ **E11y** (easy telemetry) - production-ready Ruby gem for structured business events with unique killer features:
13
13
 
14
- 1. **Request-scoped debug buffering** - debug events только при ошибках (89% reduction)
15
- 2. **Pattern-based metrics** - автоматические метрики без boilerplate
16
- 3. **Zero-config SLO tracking** - built-in monitoring одной строкой конфига
14
+ 1. **Request-scoped debug buffering** - debug events only on errors (89% reduction)
15
+ 2. **Event-level metrics DSL** - automatic metrics without boilerplate
16
+ 3. **Zero-config SLO tracking** - built-in monitoring with a single config line
17
17
 
18
18
  **Target Market:** Ruby/Rails teams (5-100 engineers)
19
- **Problem:** Observability сложна, дорога и перегружена шумом
20
- **Solution:** Простой, Rails-first gem с production-ready defaults
19
+ **Problem:** Observability is complex, expensive, and overloaded with noise
20
+ **Solution:** Simple, Rails-first gem with production-ready defaults
21
21
 
22
22
  ---
23
23
 
@@ -160,14 +160,19 @@ E11y.configure { |config| config.slo_tracking = true }
160
160
 
161
161
  #### 3. Automatic Metrics
162
162
 
163
- **Pattern-based metrics:**
163
+ **Event-level metrics DSL:**
164
164
  ```ruby
165
- # Define event once
166
- Events::OrderPaid.track(order_id: '123', amount: 99, currency: 'USD')
165
+ # Define event once with metrics
166
+ class Events::OrderPaid < E11y::Event::Base
167
+ schema { required(:order_id).filled(:string); required(:amount).filled(:float); optional(:currency).maybe(:string) }
168
+ metrics do
169
+ counter :orders_paid_total, tags: [:currency]
170
+ histogram :order_amount, value: :amount, tags: [:currency]
171
+ end
172
+ end
167
173
 
168
- # Get metrics automatically (configured via patterns)
169
- # - orders.paid.total{currency="USD"} = 1
170
- # - orders.paid.amount{currency="USD"} = 99
174
+ Events::OrderPaid.track(order_id: '123', amount: 99, currency: 'USD')
175
+ # orders_paid_total{currency="USD"} = 1, order_amount{currency="USD"} = 99
171
176
  ```
172
177
 
173
178
  **Result:** No boilerplate, no duplication, consistent.
@@ -243,7 +248,7 @@ end
243
248
  | **Setup complexity** | High (5+ pages) | Low (1 line) |
244
249
  | **Rails integration** | Manual | Automatic |
245
250
  | **Request-scoped buffering** | ❌ | ✅ |
246
- | **Pattern-based metrics** | ❌ | ✅ |
251
+ | **Event-level metrics DSL** | ❌ | ✅ |
247
252
  | **SLO tracking** | Manual setup | One-line config |
248
253
  | **Target audience** | Polyglot teams | Rails teams |
249
254
 
@@ -363,7 +368,7 @@ end
363
368
  ✅ <1ms p99 latency
364
369
 
365
370
  **v1.0 (Phase 5):**
366
- Pattern-based metrics (Yabeda)
371
+ Event-level metrics (Yabeda)
367
372
  ✅ Zero-config SLO tracking
368
373
  ✅ OpenTelemetry integration
369
374
  ✅ Cardinality protection
@@ -1,18 +1,18 @@
1
1
  # E11y Use Cases Documentation
2
2
 
3
- Эта папка содержит детальные use cases для различных сценариев использования E11y gem.
3
+ This folder contains detailed use cases for various E11y gem usage scenarios.
4
4
 
5
- ## 📁 Структура
5
+ ## 📁 Structure
6
6
 
7
7
  ### Core Use Cases
8
- - **[UC-001: Request-Scoped Debug Buffering](./UC-001-request-scoped-debug-buffering.md)** - Killer feature: debug events только при ошибках
9
- - **[UC-002: Business Event Tracking](./UC-002-business-event-tracking.md)** - Структурированные бизнес-события
10
- - **[UC-003: Pattern-Based Metrics](./UC-003-pattern-based-metrics.md)** - Автоматические метрики из событий
8
+ - **[UC-001: Request-Scoped Debug Buffering](./UC-001-request-scoped-debug-buffering.md)** - Killer feature: debug events only on errors
9
+ - **[UC-002: Business Event Tracking](./UC-002-business-event-tracking.md)** - Structured business events
10
+ - **[UC-003: Event Metrics](./UC-003-event-metrics.md)** - Metrics in event classes
11
11
  - **[UC-004: Zero-Config SLO Tracking](./UC-004-zero-config-slo-tracking.md)** - Built-in SLO monitoring
12
12
 
13
13
  ### Integration Use Cases
14
- - **[UC-005: Sentry Integration](./UC-005-sentry-integration.md)** - Error tracking с автоматическими breadcrumbs
15
- - **[UC-006: Trace Context Management](./UC-006-trace-context-management.md)** - Автоматическая корреляция через trace_id
14
+ - **[UC-005: Sentry Integration](./UC-005-sentry-integration.md)** - Error tracking with automatic breadcrumbs
15
+ - **[UC-006: Trace Context Management](./UC-006-trace-context-management.md)** - Automatic correlation via trace_id
16
16
  - **[UC-007: PII Filtering](./UC-007-pii-filtering.md)** - Rails-compatible PII filtering
17
17
  - **[UC-008: OpenTelemetry Integration](./UC-008-opentelemetry-integration.md)** - OTel compatibility
18
18
  - **[UC-009: Multi-Service Tracing](./UC-009-multi-service-tracing.md)** - Distributed tracing
@@ -34,7 +34,7 @@
34
34
  - **[UC-018: Testing Events](./UC-018-testing-events.md)** - Test strategies
35
35
  - **[UC-020: Event Versioning](./UC-020-event-versioning.md)** - Schema evolution & backward compatibility
36
36
  - **[UC-021: Error Handling & DLQ](./UC-021-error-handling-retry-dlq.md)** - Retry policy & dead letter queue
37
- - **[UC-022: Event Registry](./UC-022-event-registry.md)** - Event introspection & discovery
37
+ - **[UC-022: Event Registry](./UC-022-event-registry.md)** - Event discovery (find, event_classes, where)
38
38
 
39
39
  ## 🎯 Use Case Categories
40
40
 
@@ -42,15 +42,15 @@
42
42
 
43
43
  **Ruby/Rails Developers:**
44
44
  - UC-002 (Business Event Tracking)
45
- - UC-014 (Rails Logger Migration)
46
- - UC-015 (Local Development)
47
- - UC-016 (Testing Events)
45
+ - UC-016 (Rails Logger Migration)
46
+ - UC-017 (Local Development)
47
+ - UC-018 (Testing Events)
48
48
 
49
49
  **DevOps/SRE Engineers:**
50
50
  - UC-001 (Request-Scoped Debug Buffering)
51
51
  - UC-004 (Zero-Config SLO Tracking)
52
52
  - UC-008 (OpenTelemetry Integration)
53
- - UC-011 (Adaptive Sampling)
53
+ - UC-014 (Adaptive Sampling)
54
54
 
55
55
  **Security/Compliance Teams:**
56
56
  - UC-007 (PII Filtering)
@@ -60,7 +60,7 @@
60
60
  **Engineering Managers/CTOs:**
61
61
  - UC-015 (Cost Optimization)
62
62
  - UC-013 (High Cardinality Protection)
63
- - UC-003 (Pattern-Based Metrics)
63
+ - UC-003 (Event Metrics)
64
64
 
65
65
  ### By Complexity
66
66
 
@@ -72,7 +72,7 @@
72
72
 
73
73
  **Intermediate (15-60 min setup):**
74
74
  - UC-001 (Request-Scoped Debug Buffering)
75
- - UC-003 (Pattern-Based Metrics)
75
+ - UC-003 (Event Metrics)
76
76
  - UC-004 (Zero-Config SLO Tracking)
77
77
  - UC-006 (Trace Context Management)
78
78
  - UC-007 (PII Filtering)
@@ -89,9 +89,9 @@
89
89
 
90
90
  ### For New Users
91
91
  Start with:
92
- 1. UC-002 (Business Event Tracking) - понять основы
93
- 2. UC-015 (Local Development) - настроить локально
94
- 3. UC-004 (Zero-Config SLO Tracking) - получить метрики
92
+ 1. UC-002 (Business Event Tracking) - learn the basics
93
+ 2. UC-017 (Local Development) - set up locally
94
+ 3. UC-004 (Zero-Config SLO Tracking) - get metrics
95
95
 
96
96
  ### For Production Deployment
97
97
  Review:
@@ -103,15 +103,14 @@ Review:
103
103
  ### For Migration from Existing Tools
104
104
  See:
105
105
  1. UC-016 (Rails Logger Migration)
106
- 2. UC-008 (OpenTelemetry Integration) - если уже используете OTel
107
- 3. UC-009 (Multi-Service Tracing) - если microservices
106
+ 2. UC-008 (OpenTelemetry Integration) - if you already use OTel
107
+ 3. UC-009 (Multi-Service Tracing) - for microservices
108
108
 
109
109
  ## 🔗 Related Documentation
110
110
 
111
- - **[Quick Start Guide](../E11Y-QUICK-START.md)** - 5-minute setup
112
- - **[API Reference](../api/README.md)** - Detailed API docs
113
- - **[Architecture Overview](../architecture/README.md)** - System design
114
- - **[Configuration Guide](../configuration/README.md)** - All config options
111
+ - **[Quick Start Guide](../QUICK-START.md)** - 5-minute setup
112
+ - **[Architecture Overview](../architecture/ADR-INDEX.md)** - System design
113
+ - **[Configuration Guide](../CONFIGURATION.md)** - All config options
115
114
 
116
115
  ---
117
116
 
@@ -234,7 +234,7 @@ end
234
234
  > config.pipeline.use RoutingMiddleware # 6. Buffer routing (LAST!)
235
235
  > ```
236
236
  >
237
- > **See:** [ADR-001 Section 4.1: Middleware Execution Order](../ADR-001-architecture.md#41-middleware-execution-order-critical) and [ADR-015: Middleware Order Reference](../ADR-015-middleware-order.md) for detailed explanation.
237
+ > **See:** [ADR-001 Section 4.1: Middleware Execution Order](../architecture/ADR-001-architecture.md#41-middleware-execution-order-critical) and [ADR-015: Middleware Order Reference](../architecture/ADR-015-middleware-order.md) for detailed explanation.
238
238
 
239
239
  ---
240
240
 
@@ -275,7 +275,7 @@ end
275
275
 
276
276
  ### Dual-Buffer Architecture
277
277
 
278
- **E11y использует ДВА независимых буфера:**
278
+ **E11y uses TWO independent buffers:**
279
279
 
280
280
  ```
281
281
  ┌─────────────────────────────────────────────────────────────────┐
@@ -318,15 +318,15 @@ Background Flush Thread (200ms interval):
318
318
  ### Buffer Routing Logic
319
319
 
320
320
  ```ruby
321
- # Pseudo-code для понимания
321
+ # Pseudo-code for understanding
322
322
  def track_event(event)
323
323
  if event.severity == :debug && E11y.request_scope.active?
324
324
  # → Request-scoped buffer (Thread-local)
325
- Thread.current[:e11y_request_buffer] << event
325
+ Thread.current[:e11y_ephemeral_buffer] << event
326
326
  else
327
327
  # → Main buffer (Global SPSC ring buffer)
328
328
  E11y.main_buffer << event
329
- # Фоновый поток заберет через 200ms (или раньше если батч заполнится)
329
+ # Background thread will pick up in 200ms (or sooner if batch fills)
330
330
  end
331
331
  end
332
332
  ```
@@ -401,11 +401,17 @@ module E11y::RequestScope
401
401
  end
402
402
  ```
403
403
 
404
+ > **DevLog integration (development/test):** When the debug buffer is flushed on request
405
+ > failure, events are delivered to all registered adapters — including
406
+ > `E11y::Adapters::DevLog` (auto-registered in development/test via Railtie). Debug
407
+ > events from failed requests automatically appear in `log/e11y_dev.jsonl` and become
408
+ > visible in the TUI and Browser Overlay. See [UC-017](UC-017-local-development.md).
409
+
404
410
  ---
405
411
 
406
412
  ## 📈 Performance Impact
407
413
 
408
- > **Implementation:** See [ADR-001 Section 8.3: Resource Limits](../ADR-001-architecture.md#83-resource-limits) for architectural details and [ADR-002 Section 6: Self-Monitoring](../ADR-002-metrics-yabeda.md#6-self-monitoring) for metrics implementation.
414
+ > **Implementation:** See [ADR-001 Section 8.3: Resource Limits](../architecture/ADR-001-architecture.md#83-resource-limits) for architectural details and [ADR-002 Section 6: Self-Monitoring](../ADR-002-metrics-yabeda.md#6-self-monitoring) for metrics implementation.
409
415
 
410
416
  ### Buffer Metrics
411
417
 
@@ -413,20 +419,20 @@ end
413
419
 
414
420
  ```ruby
415
421
  # Exposed via Yabeda (auto-configured)
416
- Yabeda.e11y_request_buffer_size # Gauge: current buffer size per request
417
- Yabeda.e11y_request_buffer_flushes_total # Counter: buffer flushes by trigger
422
+ Yabeda.e11y_ephemeral_buffer_size # Gauge: current buffer size per request
423
+ Yabeda.e11y_ephemeral_buffer_flushes_total # Counter: buffer flushes by trigger
418
424
 
419
425
  # Accessible via Prometheus metrics endpoint
420
426
  # Example queries:
421
427
 
422
428
  # 1. Average buffer size
423
- avg(e11y_request_buffer_size)
429
+ avg(e11y_ephemeral_buffer_size)
424
430
 
425
431
  # 2. Buffer flush rate by trigger
426
- rate(e11y_request_buffer_flushes_total{trigger="error"}[5m])
432
+ rate(e11y_ephemeral_buffer_flushes_total{trigger="error"}[5m])
427
433
 
428
434
  # 3. Buffer overflow alerts
429
- e11y_request_buffer_size >= 100 # Alert if buffer limit reached
435
+ e11y_ephemeral_buffer_size >= 100 # Alert if buffer limit reached
430
436
  ```
431
437
 
432
438
  **Monitoring Examples:**
@@ -436,18 +442,18 @@ e11y_request_buffer_size >= 100 # Alert if buffer limit reached
436
442
 
437
443
  # Panel 1: Buffer Size Distribution
438
444
  histogram_quantile(0.99,
439
- sum(rate(e11y_request_buffer_size[5m])) by (le)
445
+ sum(rate(e11y_ephemeral_buffer_size[5m])) by (le)
440
446
  )
441
447
  # Shows p99 buffer size
442
448
 
443
449
  # Panel 2: Flush Triggers Breakdown
444
450
  sum by (trigger) (
445
- rate(e11y_request_buffer_flushes_total[5m])
451
+ rate(e11y_ephemeral_buffer_flushes_total[5m])
446
452
  )
447
453
  # Shows why buffers flush (error vs. slow_request vs. custom)
448
454
 
449
455
  # Panel 3: Memory Impact Estimate
450
- avg(e11y_request_buffer_size) * 500 # bytes per event
456
+ avg(e11y_ephemeral_buffer_size) * 500 # bytes per event
451
457
  # Estimates per-request memory usage
452
458
  ```
453
459
 
@@ -609,13 +615,13 @@ end
609
615
 
610
616
  ---
611
617
 
612
- ## 🔄 Взаимодействие с Flush Interval (200ms)
618
+ ## 🔄 Interaction with Flush Interval (200ms)
613
619
 
614
- ### Вопрос: Не конфликтуют ли буферы?
620
+ ### Question: Do the buffers conflict?
615
621
 
616
- **Ответ: НЕТ. Они независимы.**
622
+ **Answer: NO. They are independent.**
617
623
 
618
- ### Детальная Логика
624
+ ### Detailed Logic
619
625
 
620
626
  ```ruby
621
627
  # config/initializers/e11y.rb
@@ -636,9 +642,9 @@ E11y.configure do |config|
636
642
  end
637
643
  ```
638
644
 
639
- ### Поток Событий
645
+ ### Event Flow
640
646
 
641
- **Scenario 1: Обычный запрос (успешный)**
647
+ **Scenario 1: Normal request (successful)**
642
648
  ```ruby
643
649
  # Request starts
644
650
  Events::DebugEvent.track(...) # → Request buffer (thread-local)
@@ -650,7 +656,7 @@ Events::DebugEvent.track(...) # → Request buffer (thread-local)
650
656
  # → Main buffer flushed every 200ms (success event sent)
651
657
  ```
652
658
 
653
- **Scenario 2: Запрос с ошибкой**
659
+ **Scenario 2: Request with error**
654
660
  ```ruby
655
661
  # Request starts
656
662
  Events::DebugEvent.track(...) # → Request buffer
@@ -662,20 +668,20 @@ Events::DebugEvent.track(...) # → Request buffer
662
668
  # → Main buffer continues flush every 200ms (error event sent)
663
669
  ```
664
670
 
665
- **Scenario 3: Высоконагруженный сервис**
671
+ **Scenario 3: High-load service**
666
672
  ```ruby
667
- # 1000 requests/sec, каждый с 5 debug events
668
- # → 5000 debug events/sec в request buffers (thread-local)
669
- # → 99% успешных → 4950 debug events/sec DISCARDED
670
- # → 1% ошибок → 50 debug events/sec FLUSHED
673
+ # 1000 requests/sec, each with 5 debug events
674
+ # → 5000 debug events/sec in request buffers (thread-local)
675
+ # → 99% successful → 4950 debug events/sec DISCARDED
676
+ # → 1% errors → 50 debug events/sec FLUSHED
671
677
  #
672
- # Параллельно:
678
+ # In parallel:
673
679
  # → 1000 info/success events/sec → Main buffer
674
- # → Flush каждые 200ms = 5 batches/sec
675
- # → 200 events per batch (в среднем)
680
+ # → Flush every 200ms = 5 batches/sec
681
+ # → 200 events per batch (on average)
676
682
  ```
677
683
 
678
- ### Итого: Никакого Конфликта!
684
+ ### Summary: No Conflict!
679
685
 
680
686
  | Event Type | Buffer | Flush Trigger | Latency |
681
687
  |------------|--------|---------------|---------|
@@ -686,14 +692,14 @@ Events::DebugEvent.track(...) # → Request buffer
686
692
  | `:error` | Main buffer (Global SPSC) | Every 200ms (background thread) | <200ms |
687
693
  | `:fatal` | Main buffer (Global SPSC) | Every 200ms (background thread) | <200ms |
688
694
 
689
- **Преимущества двойного буфера:**
690
- 1. ✅ Debug события не засоряют main buffer
691
- 2. ✅ Важные события (info+) идут быстро (200ms)
692
- 3. ✅ Debug события идут мгновенно при ошибке (flush triggered)
693
- 4. ✅ 99% debug событий вообще не обрабатываются (discard = zero cost)
694
- 5. ✅ Thread-safety: request buffer изолирован в Thread.current
695
+ **Benefits of dual buffer:**
696
+ 1. ✅ Debug events don't clutter main buffer
697
+ 2. ✅ Important events (info+) go fast (200ms)
698
+ 3. ✅ Debug events go instantly on error (flush triggered)
699
+ 4. ✅ 99% of debug events are never processed (discard = zero cost)
700
+ 5. ✅ Thread-safety: request buffer isolated in Thread.current
695
701
 
696
- ### Визуальная Диаграмма
702
+ ### Visual Diagram
697
703
 
698
704
  ```
699
705
  Time: ──────────────────────────────────────────────────>
@@ -720,14 +726,14 @@ Background Flush Thread: │ │
720
726
  200ms 400ms
721
727
  ```
722
728
 
723
- ### Пример с Цифрами
729
+ ### Example with Numbers
724
730
 
725
- **Нагрузка:**
731
+ **Load:**
726
732
  - 100 requests/sec
727
- - Каждый запрос: 3 debug события + 1 success событие
733
+ - Each request: 3 debug events + 1 success event
728
734
  - Error rate: 1%
729
735
 
730
- **Что происходит:**
736
+ **What happens:**
731
737
 
732
738
  | Time | Request Buffer (Thread-local) | Main Buffer (Global) | Flush |
733
739
  |------|------------------------------|---------------------|-------|
@@ -739,8 +745,8 @@ Background Flush Thread: │ │
739
745
  | 210ms | Req21: [D, D, D] ERROR! | [S21, E21, **D, D, D from Req21**] | **Immediate flush debug** |
740
746
  | 400ms | - | [S21...S40] | **Flush next batch** |
741
747
 
742
- **Результат:**
743
- - Success events: ~100/sec → flush каждые 200ms → latency <200ms ✅
748
+ **Result:**
749
+ - Success events: ~100/sec → flush every 200ms → latency <200ms ✅
744
750
  - Debug events (99%): DISCARDED → zero overhead ✅
745
751
  - Debug events (1% errors): flushed IMMEDIATELY with error context ✅
746
752
 
@@ -804,7 +810,7 @@ end
804
810
 
805
811
  - **[UC-002: Business Event Tracking](./UC-002-business-event-tracking.md)** - Define structured events
806
812
  - **[UC-010: Background Job Tracking](./UC-010-background-job-tracking.md)** - Buffering in Sidekiq/ActiveJob
807
- - **[UC-015: Local Development](./UC-015-local-development.md)** - Test buffering locally
813
+ - **[UC-017: Local Development](./UC-017-local-development.md)** - Test buffering locally
808
814
 
809
815
  ---
810
816