palkan/downstream
66.9
Adequate · 22 September 2026
541
lines of production code
Ruby
primary language
7
measurements over time
What this system is
This system is a Ruby gem that provides an event-driven architecture for Rails applications, enabling developers to define and publish structured data events. It features a pluggable pub/sub adapter system that supports both synchronous and asynchronous event processing via Active Job, allowing for non-blocking dispatch. The library also includes comprehensive testing utilities, such as RSpec matchers, to verify event publishing and subscriber behavior within Rails engines.
Features
Major version 2.0: Async pub/sub, structured data events, and GlobalID support
Downstream has been upgraded to version 2.0.0, introducing a new pub/sub adapter system that supports asynchronous event processing via ActiveJob (with a default stateless adapter using ActiveSupport::Notifications). Events now support structured data payloads through a new \DataEvent\ class and a \define\ DSL, replacing the previous flat attribute model. The library also adds GlobalID support for events, allowing them to be serialized and located across services, and includes a new \Subscriber\ base class for handling events via public methods. Configuration now allows switching pub/sub adapters and setting an async queue name.
lib/downstream · high confidence
Removals
Removal of bin/rails executable
The bin/rails script has been removed from the project. This file previously served as the entry point for running Rails engine commands within the development environment, requiring the bundler setup and the engine's helper configuration.
bin · high confidence
Behavioural changes
Async event publishing and adapter-based pub/sub architecture
The library now supports asynchronous event handling via a new \async\ parameter on \subscribe\, which leverages Active Job to queue events instead of processing them immediately. This change introduces a pluggable pub/sub adapter system (defaulting to Active Support Notifications but extensible via \downstream/pubsub\_adapters/abstract\_pubsub\) and adds new core components including \Subscriber\, \DataEvent\, and \SubscriberJob\. Users can now configure the pub/sub backend and benefit from non-blocking event dispatching.
lib · high confidence
Refactored RSpec matchers for event publishing and async subscribers
The RSpec test helpers for verifying event publishing and async subscriber enqueuing have been refactored to use a new internal subscription API. The \have\_published\_event\ matcher now delegates to \Downstream.subscribed\ instead of directly wrapping \ActiveSupport::Notifications\, and its failure messages have been simplified to no longer list unmatching events. A new \have\_enqueued\_async\_subscriber\_for\ matcher has been added to allow testing of enqueued async subscribers with specific event payloads.
lib/downstream/rspec · high confidence
Switch from Standard to RuboCop and drop Rails 5 support
The project has migrated its linting tooling from Standard to RuboCop, introducing new configuration files (.rubocop.yml, .rubocop-md.yml) and updating the Rakefile and lefthook to use RuboCop tasks. This change coincides with a breaking change in the gem's compatibility: support for Rails 5 has been removed (as Rails 5 does not support callable objects for subscribers), and the minimum Ruby version is now 3.1. Consequently, the Appraisals file for Rails 5 and associated Docker/dip configurations have been deleted, and the README has been updated to reflect the new configuration options and Data-backed event payloads.
(repo-wide) · high confidence
Test coverage
Added request specs and updated test environment setup; Added test database configuration and schema stubs; Added test for subscriber reset on code reload; Added tests for event definitions, subscriber jobs, and async subscription matchers.
Dependencies
Added multi-version Rails and Rubocop gemfiles
New gemfiles have been added to support testing against specific Rails versions (7.0, 7.1, 8.0) and the Rails master branch, alongside a dedicated gemfile for Rubocop linting. This enables the project to verify compatibility and run style checks across these different environments.
gemfiles · high confidence
Update Ruby and Rails requirements; add explicit dependencies
The gem now requires Ruby 3.1+ and Rails 7+, dropping support for older versions. It adds explicit runtime dependencies on 'after\_commit\_everywhere' (\~\> 1.0) and 'globalid' (\~\> 1.0). Development dependencies have been updated, including 'rspec-rails' to \~6.0 and 'combustion' to \~1.3, while removing older dev tools like 'appraisal' and 'standard'. The Gemfile now conditionally loads Rails 7.0 and sqlite3 for local development if a local gemfile is not present.
(dependencies) · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
This is the PUBLIC form of this artifact. Findings are listed in full, but the details of SECURITY findings — which rule fired, in which file, on which line, and how to fix it — are deliberately withheld, and any secret-scanner results are excluded entirely. Where detail is absent here it was REMOVED FOR PUBLICATION; it is not missing from the analysis. The complete artifact is available from the repository owner.
Score
- CAI 55 → 67 (+12.0)
- Rubric changed (rubric-2026.08.19 → rubric-2026.09.15) — scores are not directly comparable.
Lenses
- Code Health 100 → 99 (-1.3)
- Architecture 69 → 69 (+0.0)
- Maturity 61 → 61 (+0.0)
- Readiness 63 → 70 (+6.2)
- Security 43 → 75 (+32.3)
Resolved (14)
- Coverage not included — suite not readable by the collector
- Dependency hygiene not measured — dependency manifest found but not parsed for hygiene
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- No exposed public API
- Test reliability not included
- The Usage section describes adapter defaults (stateless/pubsub, async_queue) but does not explain what happens when an adapter is configured to something other than stateless and whether it still works as advertised. (README.md)
- early-stage repository — too few commits for a meaningful bus factor
- early-stage repository — too little history to judge knowledge freshness
New (21)
- Ambiguous naming convention for subscription operations. 'subscribe' implies the action of registering, while 'subscribed' is grammatically passive or past-tense, yet both appear to handle subscription logic. It is unclear if 'subscribed' is a query method (checking if subscribed) or a registration method with a different signature.
- Documentation: no architecture or design documentation (README.md)
- Documentation: no installation or build instructions (README.md)
- Documentation: no usage examples (README.md)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- Inconsistent method signatures for the same core operation across related types. The base class 'AbstractPubsub' and its implementation 'Stateless.Pubsub' differ in parameters (presence of 'async'), forcing callers to handle type-specific logic or casting.
- Low CVE: [GHSA redacted] (Gemfile)
- Medium: security finding (details withheld)
- No dependency advisory monitoring
- Redundant configuration methods. 'config' and 'configure' are semantically identical in this context, offering no distinction in behavior or intent.
- TodoComment (lib/downstream/event.rb)
- TodoComment (lib/downstream/subscriber.rb)
- TodoComment (lib/downstream/subscriber.rb)
- …and 1 more
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
palkan/downstream was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 22 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit 86a136501acda6671714234c6b667625357b1c03 — the exact code this score is about.
- Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-821afab8930d.