Skip to the content.

ADR 0014: Ship Bundler and RubyGems plugins as v1 interfaces

Status: Accepted (amended by ADR-0015 on shipping order) Date: 2026-05-03 Amends: ADR-0006, ADR-0012 Amended by: ADR-0015 — plugin shims defer from v1.0 to v1.x; the “plugins live inside gem-contribute, not as separate gems” architectural decision in this ADR is preserved unchanged

Context

ADR-0006 (2026-04-27) decided to ship as a standalone gem rather than a Bundler plugin. The primary reason was workshop scope — Bundler plugin authoring would distract attendees from the actual learning objectives (Ratatui, OAuth, GitHub’s API). It explicitly left the door open: “A future ADR can revisit this if the tool sees real adoption and the plugin UX becomes the bottleneck.”

ADR-0012 (2026-05-03 morning) added a RubyGems plugin (gem contribute) as a third interface, alongside the standalone CLI and the (then-bubbletea) TUI. It noted that the Bundler plugin decision in ADR-0006 was unchanged.

The Blue Ridge Ruby workshop concluded 2026-05-02. ADR-0006’s workshop-scope concern is no longer load-bearing.

Separately: the v1 release goal now includes both bundle contribute and gem contribute as discoverable entry points, alongside gem-contribute itself. This makes the tool reachable from whatever invocation surface a user is already in.

Decision

Ship three entry points for v1:

  1. gem-contribute — standalone CLI binary. Bare invocation (no subcommand) launches the Rooibos TUI. Subcommands run as CLI verbs.
  2. bundle contribute — Bundler plugin. CLI-only. Bare invocation runs a default summary verb (TBD: scan vs list all). Subcommands run as CLI verbs.
  3. gem contribute — RubyGems plugin. CLI-only. Same shape as bundle contribute.

All three entry points ship in a single gem (gem-contribute). One gem install gem-contribute registers the standalone binary, the Bundler plugin, and the RubyGems plugin.

Reasoning

The workshop scope-creep argument has expired. ADR-0006’s central rejection was “plugin authoring would distract workshop attendees.” Workshop is done; the v1 audience is end users and contributors, not workshop attendees. The remaining ADR-0006 reasoning (UX nicety of bundle X) actually supports shipping plugins.

Plugin entry points are CLI-only, by design. Bundler and RubyGems plugin ecosystems are built around CLI subcommands, not interactive TUIs. Users running bundle contribute expect the same kind of behavior as bundle exec, bundle install, etc. — text in, text out. The TUI is a property of the standalone binary; the plugins delegate into the same service-layer entry points the CLI uses.

This has a useful architectural consequence: the plugin entry points never need to load Rooibos or ratatui_ruby. Plugin install stays lightweight, and plugin invocations don’t pay the TUI startup cost.

One gem rather than three. ADR-0012 sketched a future rubygems-contribute gem. Three gems would follow Ruby ecosystem convention (bundler-X, rubygems-X) but tripples release ceremony, version coordination, and CHANGELOG maintenance. For a project this size, that cost is not earned. One gem with three entry points: one gem install, one CHANGELOG, one version, all three interfaces work.

ADR-0012’s three-interface framing carries over unchanged. The service layer (output-free, returns Result) is what enables three interfaces to share code. ADR-0014 doesn’t add a fourth interface; it confirms the third (Bundler plugin) and locks the packaging to a single gem.

Alternatives considered

Consequences

On the gemspec:

On lib/gem_contribute/cli.rb:

On the Bundler plugin entry point: must not require Rooibos or ratatui_ruby at load time. TUI loading is gated to the standalone-binary entry point only.

On ADR-0006: status updated to note ADR-0014 amends it. The standalone-gem decision stands; the no-Bundler-plugin decision is reversed.

On ADR-0012: status updated to note ADR-0014 amends it. The three-interface architecture is preserved; the planned separate rubygems-contribute gem is replaced by a single gem-contribute gem with three entry points.

On docs/design-interface-layer.md: “gem plugin pipeline” section needs updating — the plugin shim is internal to the gem-contribute gem, not a separate rubygems-contribute gem. Same change for the Bundler plugin section (which doesn’t yet exist; needs adding).

On testing: add at least one smoke test per plugin entry point that proves the plugin registers and dispatches a verb without booting the TUI. Implementation tests live in the existing CLI verb specs (verbs aren’t aware of which entry point invoked them).

On release: the bundle plugin install gem-contribute and gem install gem-contribute paths both need verification before v1 ships. Add to Phase 6 acceptance.

What this doesn’t change