Skip to content

docs: RFC 0002 — Plugin architecture with Ledger v3 as POC#154

Open
gfyrag wants to merge 3 commits into
mainfrom
rfc/plugin-architecture-ledger-v3
Open

docs: RFC 0002 — Plugin architecture with Ledger v3 as POC#154
gfyrag wants to merge 3 commits into
mainfrom
rfc/plugin-architecture-ledger-v3

Conversation

@gfyrag
Copy link
Copy Markdown
Contributor

@gfyrag gfyrag commented May 15, 2026

Summary

Key design decisions

  • Plugins live in product repos at cmd/fctl-plugin/ — ownership, versioning, and CI stay with the product team
  • Plugin version = service version — enforced, not a convention. Eliminates version mapping confusion
  • Registry is minimal — just compatibleWith semver ranges. Binary URLs derived from convention ({repo}/releases/download/v{version}/fctl-plugin-{name}-{os}-{arch})
  • Built-in commands stay for Ledger v2 — zero disruption for existing users. Plugin only activates for v3+
  • Resolution order: plugin first → built-in fallback → auto-discovery
  • Works at any semver granularity — minor version differences get their own plugin version, no intra-version feature-gating needed
  • No fctl plugin update — lifecycle is fully driven by auto-discovery when the service version changes
  • Rendering centralized in fctl core — plugins return structured data, fctl renders via display schemas

User journeys covered

  1. Cloud user gets the right plugin via auto-discovery
  2. Switching between Ledger v2 (built-in) and v3 (plugin) stacks transparently
  3. Self-hosted user with /versions detection
  4. Local developer building from cmd/fctl-plugin/ in the ledger repo
  5. Debugging across the plugin boundary (--debug with [fctl]/[plugin] prefixes)
  6. Error handling when plugin is missing (auto-discovery first, actionable errors in non-interactive mode)
  7. Version retirement via registry deprecation notices

Related

🤖 Generated with Claude Code

@gfyrag gfyrag requested a review from a team as a code owner May 15, 2026 12:51
Proposes a plugin-based architecture for fctl where product CLI commands
ship as independent binaries from product repos. Uses Ledger v3 as the
concrete proof of concept with detailed user journeys covering Cloud,
self-hosted, local dev, debugging, error handling, and version retirement.

Key design decisions:
- Plugins live in product repos at cmd/fctl-plugin/
- Plugin version = service version (enforced)
- Registry derives binary URLs from convention
- Built-in commands remain for Ledger v2, plugin activates for v3+
- Resolution: plugin first, built-in fallback, auto-discovery last
- Rendering centralized in fctl core via display schemas
- Plugin lifecycle fully driven by auto-discovery, no manual updates

Relates to #126 and #153.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@gfyrag gfyrag force-pushed the rfc/plugin-architecture-ledger-v3 branch from 61cb6ee to c2c6780 Compare May 15, 2026 12:53
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 15, 2026

Review Change Stack

Warning

Rate limit exceeded

@gfyrag has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 33 minutes and 9 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9e577ada-06ba-4bca-98c3-8d30ea69f88d

📥 Commits

Reviewing files that changed from the base of the PR and between 2c531a2 and 11a1747.

📒 Files selected for processing (1)
  • docs/rfcs/0002-plugin-architecture-ledger-v3-poc.md
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch rfc/plugin-architecture-ledger-v3

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@flemzord
Copy link
Copy Markdown
Member

One point we should clarify early: using GitHub releases as the default plugin distribution mechanism works for Ledger because the repository is public, but it may not work as a general registry/distribution model for fctl plugins.

Some product repositories may be private, or may become private depending on the product / customer / deployment model. In that case, deriving plugin binary URLs from https://github.com/{repo}/releases/download/... creates a hidden assumption that the plugin artifact is publicly reachable by every fctl user.

For the Ledger v3 POC this is fine, but I think the RFC should explicitly separate:

  • the plugin registry metadata (name, repo, compatibleWith, deprecation, etc.);
  • the artifact distribution backend;
  • the authentication/authorization story for downloading private plugins.

Otherwise we may validate the POC on the easiest case, but leave the harder product cases unresolved.

Maybe the RFC can keep GitHub releases as the initial Ledger POC distribution backend, while making it clear that the registry abstraction must support non-public artifact sources later.

gfyrag and others added 2 commits May 15, 2026 15:17
Address review feedback: GitHub releases as default distribution backend
works for public repos (Ledger POC) but not for private product repos.

Registry now explicitly separates metadata (compatibleWith, deprecation)
from distribution backend (github-releases, private-releases, oci, url).
The format supports private and enterprise scenarios from the start.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
A lightweight Formance-hosted service (plugins.formance.cloud) serves
plugin binaries using the existing membership token. Avoids GitHub token
dependency for private repos and provides uniform auth, caching, and
server-side version control.

GitHub releases remains the default for the POC (public repo).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@laouji laouji left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally speaking this looks very good.

Having the fctl plugins bundled in the repo of the module also means we can more easily wire up end to end tests that use fctl and more easily detect if changes break compatibility with fctl.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants