e11y 0.1.0 → 0.2.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 (70) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +1 -0
  3. data/.rubocop.yml +20 -0
  4. data/CHANGELOG.md +151 -13
  5. data/README.md +1138 -104
  6. data/RELEASE.md +254 -0
  7. data/Rakefile +377 -0
  8. data/benchmarks/OPTIMIZATION.md +246 -0
  9. data/benchmarks/README.md +103 -0
  10. data/benchmarks/allocation_profiling.rb +253 -0
  11. data/benchmarks/e11y_benchmarks.rb +447 -0
  12. data/benchmarks/ruby_baseline_allocations.rb +175 -0
  13. data/benchmarks/run_all.rb +9 -21
  14. data/docs/00-ICP-AND-TIMELINE.md +2 -2
  15. data/docs/ADR-001-architecture.md +1 -1
  16. data/docs/ADR-004-adapter-architecture.md +247 -0
  17. data/docs/ADR-009-cost-optimization.md +231 -115
  18. data/docs/ADR-017-multi-rails-compatibility.md +103 -0
  19. data/docs/ADR-INDEX.md +99 -0
  20. data/docs/CONTRIBUTING.md +312 -0
  21. data/docs/IMPLEMENTATION_PLAN.md +1 -1
  22. data/docs/QUICK-START.md +0 -6
  23. data/docs/use_cases/UC-019-retention-based-routing.md +584 -0
  24. data/e11y.gemspec +28 -17
  25. data/lib/e11y/adapters/adaptive_batcher.rb +3 -0
  26. data/lib/e11y/adapters/audit_encrypted.rb +10 -4
  27. data/lib/e11y/adapters/base.rb +15 -0
  28. data/lib/e11y/adapters/file.rb +4 -1
  29. data/lib/e11y/adapters/in_memory.rb +6 -0
  30. data/lib/e11y/adapters/loki.rb +9 -0
  31. data/lib/e11y/adapters/otel_logs.rb +11 -9
  32. data/lib/e11y/adapters/sentry.rb +9 -0
  33. data/lib/e11y/adapters/yabeda.rb +54 -10
  34. data/lib/e11y/buffers.rb +8 -8
  35. data/lib/e11y/console.rb +52 -60
  36. data/lib/e11y/event/base.rb +75 -10
  37. data/lib/e11y/event/value_sampling_config.rb +10 -4
  38. data/lib/e11y/events/rails/http/request.rb +1 -1
  39. data/lib/e11y/instruments/active_job.rb +6 -3
  40. data/lib/e11y/instruments/rails_instrumentation.rb +51 -28
  41. data/lib/e11y/instruments/sidekiq.rb +7 -7
  42. data/lib/e11y/logger/bridge.rb +24 -54
  43. data/lib/e11y/metrics/cardinality_protection.rb +257 -12
  44. data/lib/e11y/metrics/cardinality_tracker.rb +17 -0
  45. data/lib/e11y/metrics/registry.rb +6 -2
  46. data/lib/e11y/metrics/relabeling.rb +0 -56
  47. data/lib/e11y/metrics.rb +6 -1
  48. data/lib/e11y/middleware/audit_signing.rb +12 -9
  49. data/lib/e11y/middleware/pii_filter.rb +18 -10
  50. data/lib/e11y/middleware/request.rb +10 -4
  51. data/lib/e11y/middleware/routing.rb +117 -90
  52. data/lib/e11y/middleware/sampling.rb +47 -28
  53. data/lib/e11y/middleware/trace_context.rb +40 -11
  54. data/lib/e11y/middleware/validation.rb +20 -2
  55. data/lib/e11y/middleware/versioning.rb +1 -1
  56. data/lib/e11y/pii.rb +7 -7
  57. data/lib/e11y/railtie.rb +24 -20
  58. data/lib/e11y/reliability/circuit_breaker.rb +3 -0
  59. data/lib/e11y/reliability/dlq/file_storage.rb +16 -5
  60. data/lib/e11y/reliability/dlq/filter.rb +3 -0
  61. data/lib/e11y/reliability/retry_handler.rb +4 -0
  62. data/lib/e11y/sampling/error_spike_detector.rb +16 -5
  63. data/lib/e11y/sampling/load_monitor.rb +13 -4
  64. data/lib/e11y/self_monitoring/reliability_monitor.rb +3 -0
  65. data/lib/e11y/version.rb +1 -1
  66. data/lib/e11y.rb +86 -9
  67. metadata +83 -38
  68. data/docs/use_cases/UC-019-tiered-storage-migration.md +0 -562
  69. data/lib/e11y/middleware/pii_filtering.rb +0 -280
  70. data/lib/e11y/middleware/slo.rb +0 -168
@@ -0,0 +1,103 @@
1
+ # ADR-017: Multi-Rails Version Compatibility
2
+
3
+ **Status:** Accepted
4
+ **Date:** January 26, 2026
5
+ **Covers:** Cross-cutting concern
6
+ **Depends On:** ADR-008 (Rails Integration)
7
+
8
+ ---
9
+
10
+ ## Context & Problem
11
+
12
+ E11y initially supported only Rails 8.0, limiting adoption:
13
+ - ~40% of Rails apps still on 7.x
14
+ - Enterprise upgrades take 12-18 months
15
+ - No migration path for Rails 7 users
16
+
17
+ ---
18
+
19
+ ## Decision
20
+
21
+ Support Rails 7.0, 7.1, 8.0 with dynamic version detection.
22
+
23
+ **Implementation:**
24
+
25
+ ```ruby
26
+ # Gemfile
27
+ rails_version = ENV.fetch('RAILS_VERSION', '8.0')
28
+ gem 'rails', "~> #{rails_version}.0", "< 8.1"
29
+
30
+ if rails_version.to_f < 8.0
31
+ gem 'sqlite3', '~> 1.4' # Rails 7.x
32
+ else
33
+ gem 'sqlite3', '~> 2.0' # Rails 8.x
34
+ end
35
+ ```
36
+
37
+ **CI Matrix:**
38
+ ```yaml
39
+ matrix:
40
+ ruby: ['3.2', '3.3']
41
+ rails: ['7.0', '7.1', '8.0']
42
+ # Total: 6 combinations
43
+ ```
44
+
45
+ ---
46
+
47
+ ## Consequences
48
+
49
+ ### Positive
50
+ - Doubles potential user base
51
+ - Enterprise-friendly (slower upgrade cycles)
52
+ - Migration path (use E11y during Rails upgrade)
53
+ - Full feature parity (no degradation)
54
+
55
+ ### Negative
56
+ - CI time: 5min → 15min (3× Rails versions)
57
+ - Maintenance: 3 Rails versions to test
58
+ - Conditional code (2 places only)
59
+
60
+ ---
61
+
62
+ ## Version-Specific Code
63
+
64
+ **1. Exception handling (Rails 8.0 changed behavior):**
65
+ ```ruby
66
+ if Rails.version.to_f >= 8.0
67
+ expect(response.status).to eq(500) # Rails 8.0: caught
68
+ else
69
+ expect { get '/error' }.to raise_error # Rails 7.x: raised
70
+ end
71
+ ```
72
+
73
+ **2. sqlite3 dependency (Gemfile only)**
74
+
75
+ ---
76
+
77
+ ## Maintenance Plan
78
+
79
+ **Drop Rails 7.0 when:**
80
+ - Rails 7.0 EOL (~2027)
81
+ - <5% users on Rails 7.0
82
+ - Rails 9.0 released
83
+
84
+ **Review quarterly:** Check market share, update CI matrix.
85
+
86
+ ---
87
+
88
+ ## Alternatives Considered
89
+
90
+ 1. **Rails 8.0 only** - Rejected: excludes 40% users
91
+ 2. **Rails 6.x support** - Rejected: EOL June 2024
92
+ 3. **Backport gem** - Rejected: doubles maintenance
93
+
94
+ ---
95
+
96
+ ## Success Metrics
97
+
98
+ | Metric | Target | Current |
99
+ |--------|--------|---------|
100
+ | Test pass rate | 100% | 100% ✅ |
101
+ | Code coverage | ≥95% | 96.46% ✅ |
102
+ | Version checks | <10 | 2 ✅ |
103
+ | CI time | <20min | ~15min ✅ |
data/docs/ADR-INDEX.md ADDED
@@ -0,0 +1,99 @@
1
+ # Architecture Decision Records (ADR) Index
2
+
3
+ This document provides an index of all architectural decisions made for the E11y gem.
4
+
5
+ ## 📋 Index
6
+
7
+ | ADR | Title | Status | Phase |
8
+ |-----|-------|--------|-------|
9
+ | [ADR-001](ADR-001-architecture.md) | Architecture & Design Principles | ✅ Accepted | 0 |
10
+ | [ADR-002](ADR-002-metrics-yabeda.md) | Metrics Integration (Yabeda) | ✅ Accepted | 2 |
11
+ | [ADR-003](ADR-003-slo-observability.md) | SLO Observability | ✅ Accepted | 2 |
12
+ | [ADR-004](ADR-004-adapter-architecture.md) | Adapter Architecture | ✅ Accepted | 2 |
13
+ | [ADR-005](ADR-005-tracing-context.md) | Tracing Context Propagation | ✅ Accepted | 2 |
14
+ | [ADR-006](ADR-006-security-compliance.md) | Security & Compliance (GDPR/SOC2) | ✅ Accepted | 2 |
15
+ | [ADR-007](ADR-007-opentelemetry-integration.md) | OpenTelemetry Integration | ✅ Accepted | 3 |
16
+ | [ADR-008](ADR-008-rails-integration.md) | Rails Integration Strategy | ✅ Accepted | 3 |
17
+ | [ADR-009](ADR-009-cost-optimization.md) | Cost Optimization Strategies | ✅ Accepted | 4 |
18
+ | [ADR-010](ADR-010-developer-experience.md) | Developer Experience (DX) | ✅ Accepted | 5 |
19
+ | [ADR-011](ADR-011-testing-strategy.md) | Testing Strategy | ✅ Accepted | 5 |
20
+ | [ADR-012](ADR-012-event-evolution.md) | Event Schema Evolution | ✅ Accepted | 1 |
21
+ | [ADR-013](ADR-013-reliability-error-handling.md) | Reliability & Error Handling | ✅ Accepted | 4 |
22
+ | [ADR-014](ADR-014-event-driven-slo.md) | Event-Driven SLO Tracking | ✅ Accepted | 3 |
23
+ | [ADR-015](ADR-015-middleware-order.md) | Middleware Execution Order | ✅ Accepted | 2 |
24
+ | [ADR-016](ADR-016-self-monitoring-slo.md) | Self-Monitoring SLO | ✅ Accepted | 4 |
25
+
26
+ ## 🎯 Key Decisions by Topic
27
+
28
+ ### Architecture & Design
29
+ - **ADR-001**: Core architecture principles, zero-allocation pattern, convention over configuration
30
+ - **ADR-012**: Event schema evolution strategy with versioning
31
+
32
+ ### Performance & Scale
33
+ - **ADR-001 §5**: Performance requirements (1K/10K/100K events/sec)
34
+ - **ADR-009**: Cost optimization strategies (adaptive sampling, compression, tiered storage)
35
+
36
+ ### Reliability & Operations
37
+ - **ADR-013**: Circuit breakers, retry policies, dead letter queues
38
+ - **ADR-016**: Self-monitoring SLO targets
39
+
40
+ ### Integration & Adapters
41
+ - **ADR-004**: Pluggable adapter architecture
42
+ - **ADR-007**: OpenTelemetry integration for distributed tracing
43
+ - **ADR-008**: Rails integration patterns (Railtie, instrumentation)
44
+
45
+ ### Observability
46
+ - **ADR-002**: Yabeda metrics integration
47
+ - **ADR-003**: SLO observability patterns
48
+ - **ADR-014**: Event-driven SLO tracking
49
+
50
+ ### Security & Compliance
51
+ - **ADR-006**: GDPR/SOC2 compliance (PII filtering, audit trails, encryption)
52
+ - **ADR-005**: Trace context propagation
53
+
54
+ ### Developer Experience
55
+ - **ADR-010**: Developer experience priorities (5-min setup, conventions)
56
+ - **ADR-011**: Testing strategy (RSpec, integration tests, benchmarks)
57
+ - **ADR-015**: Middleware execution order guarantees
58
+
59
+ ## 📚 Decision Process
60
+
61
+ All ADRs follow this structure:
62
+
63
+ 1. **Context** - The issue motivating this decision
64
+ 2. **Decision** - The change that we're proposing or have agreed to
65
+ 3. **Consequences** - What becomes easier or more difficult to do
66
+
67
+ ## 🔄 Status Legend
68
+
69
+ - ✅ **Accepted** - Decision is final and implemented
70
+ - 🔄 **Proposed** - Under review
71
+ - ❌ **Rejected** - Decision was not accepted
72
+ - ⚠️ **Deprecated** - Superseded by a newer decision
73
+
74
+ ## 📖 How to Read ADRs
75
+
76
+ ### For New Contributors
77
+ Start with:
78
+ 1. [ADR-001](ADR-001-architecture.md) - Core architecture principles
79
+ 2. [ADR-010](ADR-010-developer-experience.md) - Developer experience goals
80
+ 3. [ADR-008](ADR-008-rails-integration.md) - Rails integration patterns
81
+
82
+ ### For Production Deployment
83
+ Review:
84
+ 1. [ADR-013](ADR-013-reliability-error-handling.md) - Reliability patterns
85
+ 2. [ADR-006](ADR-006-security-compliance.md) - Security & compliance
86
+ 3. [ADR-009](ADR-009-cost-optimization.md) - Cost optimization
87
+
88
+ ### For Performance Tuning
89
+ See:
90
+ 1. [ADR-001 §5](ADR-001-architecture.md) - Performance requirements
91
+ 2. [ADR-009](ADR-009-cost-optimization.md) - Optimization strategies
92
+ 3. [docs/guides/performance-tuning.md](guides/performance-tuning.md) - Tuning guide
93
+
94
+ ## 🔗 Related Documentation
95
+
96
+ - [Implementation Plan](IMPLEMENTATION_PLAN.md) - Detailed development timeline
97
+ - [Use Cases](use_cases/) - User scenarios and requirements
98
+ - [API Reference](API.md) - Public API documentation
99
+ - [Guides](guides/) - How-to guides for common tasks
@@ -0,0 +1,312 @@
1
+ # Contributing to E11y
2
+
3
+ Thank you for your interest in contributing to E11y! This document provides guidelines and instructions for contributing.
4
+
5
+ ## 📋 Table of Contents
6
+
7
+ - [Getting Started](#getting-started)
8
+ - [Development Setup](#development-setup)
9
+ - [Running Tests](#running-tests)
10
+ - [Code Style](#code-style)
11
+ - [Submitting Changes](#submitting-changes)
12
+
13
+ ## 🚀 Getting Started
14
+
15
+ ### Prerequisites
16
+
17
+ - **Ruby 3.2+** (recommended: 3.3+)
18
+ - **Bundler 2.0+**
19
+ - **Docker & Docker Compose** (for integration tests)
20
+ - **Git**
21
+
22
+ ### Fork and Clone
23
+
24
+ ```bash
25
+ # Fork the repository on GitHub
26
+ # Then clone your fork
27
+ git clone git@github.com:YOUR_USERNAME/e11y.git
28
+ cd e11y
29
+ ```
30
+
31
+ ## 🔧 Development Setup
32
+
33
+ ### 1. Install Dependencies
34
+
35
+ ```bash
36
+ # Run setup script (configures bundle, installs dependencies)
37
+ bin/setup
38
+ ```
39
+
40
+ This will:
41
+ - Configure bundle to exclude integration dependencies by default
42
+ - Install core dependencies
43
+ - Display available commands
44
+
45
+ ### 2. Install Integration Dependencies (Optional)
46
+
47
+ For working on Rails integration, OpenTelemetry adapter, or other integrations:
48
+
49
+ ```bash
50
+ bundle install --with integration
51
+ ```
52
+
53
+ This installs:
54
+ - Rails 8.0
55
+ - OpenTelemetry SDK
56
+ - RSpec Rails
57
+ - Database Cleaner
58
+
59
+ ## 🧪 Running Tests
60
+
61
+ E11y has two types of tests:
62
+
63
+ ### Unit Tests (Default)
64
+
65
+ Fast, isolated tests without external dependencies:
66
+
67
+ ```bash
68
+ bundle exec rspec
69
+ ```
70
+
71
+ - **Duration**: ~2 minutes
72
+ - **Coverage**: 100% required
73
+ - **When to run**: Before every commit
74
+
75
+ ### Integration Tests
76
+
77
+ Full tests with Rails, OpenTelemetry SDK, and docker-compose services:
78
+
79
+ ```bash
80
+ # Option 1: Using helper script (recommended)
81
+ bin/test-integration
82
+
83
+ # Option 2: Manual
84
+ docker-compose up -d
85
+ INTEGRATION=true bundle exec rspec --tag integration
86
+ docker-compose down
87
+ ```
88
+
89
+ - **Duration**: ~5 minutes
90
+ - **When to run**: Before submitting PR, when changing integrations
91
+ - **Requirements**: Docker, integration dependencies installed
92
+
93
+ See [Integration Testing Guide](testing/integration-tests.md) for detailed instructions.
94
+
95
+ ### Running Specific Tests
96
+
97
+ ```bash
98
+ # Run specific file
99
+ bundle exec rspec spec/e11y/event/base_spec.rb
100
+
101
+ # Run specific example
102
+ bundle exec rspec spec/e11y/event/base_spec.rb:42
103
+
104
+ # Run tests matching pattern
105
+ bundle exec rspec --tag validation
106
+ ```
107
+
108
+ ## 📝 Code Style
109
+
110
+ E11y follows the Ruby community style guide with RuboCop:
111
+
112
+ ### Run Linter
113
+
114
+ ```bash
115
+ # Check code style
116
+ bundle exec rubocop
117
+
118
+ # Auto-fix issues
119
+ bundle exec rubocop -a
120
+ ```
121
+
122
+ ### Key Conventions
123
+
124
+ - **100% test coverage** required
125
+ - **Type-safe code** - use dry-schema, dry-types
126
+ - **Thread-safe** - avoid shared mutable state
127
+ - **Performance-conscious** - zero-allocation patterns where possible
128
+ - **Documentation** - YARD comments for public APIs
129
+
130
+ ## 🔒 Security
131
+
132
+ ### Run Security Audits
133
+
134
+ ```bash
135
+ # Check for vulnerable dependencies
136
+ bundle exec bundler-audit check --update
137
+
138
+ # Static security analysis
139
+ bundle exec brakeman
140
+ ```
141
+
142
+ ## 📦 Submitting Changes
143
+
144
+ ### 1. Create a Branch
145
+
146
+ ```bash
147
+ git checkout -b feature/your-feature-name
148
+ # or
149
+ git checkout -b fix/issue-description
150
+ ```
151
+
152
+ ### 2. Make Your Changes
153
+
154
+ - Write tests first (TDD)
155
+ - Ensure all tests pass
156
+ - Update documentation
157
+ - Follow code style guidelines
158
+
159
+ ### 3. Commit Your Changes
160
+
161
+ ```bash
162
+ git add .
163
+ git commit -m "feat: add awesome feature
164
+
165
+ - Added X functionality
166
+ - Updated Y documentation
167
+ - Fixed Z edge case
168
+
169
+ Closes #123"
170
+ ```
171
+
172
+ Use [Conventional Commits](https://www.conventionalcommits.org/):
173
+ - `feat:` - New feature
174
+ - `fix:` - Bug fix
175
+ - `docs:` - Documentation only
176
+ - `refactor:` - Code refactoring
177
+ - `test:` - Adding tests
178
+ - `chore:` - Maintenance tasks
179
+
180
+ ### 4. Push and Create Pull Request
181
+
182
+ ```bash
183
+ git push origin feature/your-feature-name
184
+ ```
185
+
186
+ Then create a PR on GitHub with:
187
+ - Clear description of changes
188
+ - Link to related issue
189
+ - Screenshots (if UI changes)
190
+ - Test results
191
+
192
+ ### 5. PR Review Process
193
+
194
+ Your PR will be reviewed for:
195
+ - ✅ All tests pass (unit + integration in CI)
196
+ - ✅ 100% code coverage maintained
197
+ - ✅ RuboCop passes
198
+ - ✅ Security audits pass
199
+ - ✅ Documentation updated
200
+ - ✅ Follows coding conventions
201
+
202
+ ## 🐛 Reporting Bugs
203
+
204
+ ### Before Reporting
205
+
206
+ 1. Search existing issues
207
+ 2. Check if bug still exists in main branch
208
+ 3. Reproduce with minimal example
209
+
210
+ ### Bug Report Template
211
+
212
+ ```markdown
213
+ **Describe the bug**
214
+ A clear description of what the bug is.
215
+
216
+ **To Reproduce**
217
+ Steps to reproduce:
218
+ 1. Configure E11y with...
219
+ 2. Call `SomeEvent.track(...)`
220
+ 3. See error
221
+
222
+ **Expected behavior**
223
+ What you expected to happen.
224
+
225
+ **Actual behavior**
226
+ What actually happened.
227
+
228
+ **Environment**
229
+ - Ruby version: 3.3.0
230
+ - E11y version: 0.1.0
231
+ - Rails version (if applicable): 8.0.0
232
+ - OS: macOS 14.0
233
+
234
+ **Additional context**
235
+ Any other relevant information.
236
+ ```
237
+
238
+ ## 💡 Suggesting Features
239
+
240
+ ### Feature Request Template
241
+
242
+ ```markdown
243
+ **Problem**
244
+ What problem does this solve?
245
+
246
+ **Proposed Solution**
247
+ How should E11y solve this?
248
+
249
+ **Alternatives**
250
+ What alternatives have you considered?
251
+
252
+ **Additional Context**
253
+ Examples, use cases, references.
254
+ ```
255
+
256
+ ## 📚 Development Resources
257
+
258
+ ### Documentation
259
+
260
+ - [Architecture Decisions (ADRs)](../docs/)
261
+ - [Implementation Plan](IMPLEMENTATION_PLAN.md)
262
+ - [API Reference](API.md)
263
+ - [Integration Testing Guide](testing/integration-tests.md)
264
+
265
+ ### Code Structure
266
+
267
+ ```
268
+ lib/e11y/
269
+ ├── event/ # Event system
270
+ ├── adapters/ # Backend adapters
271
+ ├── buffers/ # Memory buffers
272
+ ├── middleware/ # Pipeline middleware
273
+ ├── reliability/ # Retry, circuit breaker, DLQ
274
+ ├── sampling/ # Sampling strategies
275
+ ├── self_monitoring/ # Internal metrics
276
+ └── slo/ # SLO tracking
277
+ ```
278
+
279
+ ### Useful Commands
280
+
281
+ ```bash
282
+ # Interactive console
283
+ bin/console
284
+
285
+ # Generate documentation
286
+ bundle exec yard doc
287
+
288
+ # Performance benchmarks
289
+ bundle exec ruby benchmarks/run_all.rb
290
+
291
+ # Check for breaking changes
292
+ bundle exec ruby scripts/check_compatibility.rb
293
+ ```
294
+
295
+ ## 🤝 Code of Conduct
296
+
297
+ By participating in this project, you agree to abide by our [Code of Conduct](../CODE_OF_CONDUCT.md).
298
+
299
+ ## 📧 Getting Help
300
+
301
+ - **Questions**: Open a GitHub Discussion
302
+ - **Bugs**: Open a GitHub Issue
303
+ - **Security**: Email security@e11y.dev (private disclosure)
304
+
305
+ ## 🎉 Recognition
306
+
307
+ Contributors are recognized in:
308
+ - [CHANGELOG.md](../CHANGELOG.md)
309
+ - GitHub Contributors page
310
+ - Release notes
311
+
312
+ Thank you for contributing to E11y! 🚀
@@ -1581,7 +1581,7 @@ PHASE 5: SCALE & OPTIMIZATION (Weeks 21-26)
1581
1581
  1. **Gemspec**
1582
1582
  - File: `e11y.gemspec`
1583
1583
  - Dependencies (dry-schema, yabeda, concurrent-ruby)
1584
- - Version (1.0.0)
1584
+ - Version (0.1.0)
1585
1585
  - License (MIT)
1586
1586
  - ✅ DoD: Gem builds successfully
1587
1587
 
data/docs/QUICK-START.md CHANGED
@@ -925,10 +925,4 @@ Yabeda.e11y.track_duration_seconds # p99 should be <1ms
925
925
  - [ ] Monitor performance
926
926
  - [ ] Rollout to production (canary 1% → 10% → 100%)
927
927
 
928
- ---
929
-
930
- **Questions?** See `e11y-final-spec.md` FAQ section or open GitHub issue.
931
-
932
- **Version**: 1.0.0
933
- **Last Updated**: 2025-12-24
934
928