ADR 003 Plugin Architecture
ADR-003: Plugin Architecture for Data Ingestion
Status: Proposed
Date: 2025-04-23
Decision makers: Jarrod Barnes (Founder), Core Eng Team
Context: Arc Memory needs to support multiple data sources beyond Git, GitHub, and ADRs. This ADR outlines the plugin architecture that will enable extensible data ingestion.
1 · Problem Statement
Arc Memory currently has hardcoded ingestors for Git, GitHub, and ADRs. As we expand to support additional data sources like Notion, Jira, Linear, and G-Suite, we need a flexible architecture that:
- Allows adding new data sources without modifying core code
- Maintains a consistent interface for all data sources
- Supports incremental builds for efficient updates
- Enables third-party developers to create their own integrations
- Preserves type safety and testability
2 · Proposed Solution
We will implement a plugin architecture based on Python’s Protocol pattern and entry point discovery system.
2.1 IngestorPlugin Protocol
2.2 IngestorRegistry
2.3 Plugin Discovery
2.4 Integration with Build Process
3 · Alternatives Considered
3.1 Class Inheritance
We considered using a base class with abstract methods instead of a Protocol:
Pros:
- Enforces implementation of required methods at instantiation time
- Can provide default implementations for some methods
Cons:
- Less flexible than Protocol (requires inheritance)
- More difficult to adapt existing classes
- Doesn’t work well with multiple inheritance
3.2 Function-Based Plugins
We considered a simpler approach using functions as plugins:
Pros:
- Simpler implementation
- Less boilerplate
Cons:
- Less structured
- Harder to maintain type safety
- Doesn’t encapsulate related functionality
3.3 Plugin Configuration Files
We considered requiring plugins to be registered in a configuration file:
Pros:
- More explicit control over which plugins are loaded
- Can configure plugin parameters
Cons:
- More complex setup for users
- Requires additional configuration parsing
- Less discoverable
4 · Impact
4.1 Positive Impacts
- Extensibility: Easy addition of new data sources
- Decoupling: Data source implementations are isolated from core code
- Consistency: All data sources follow the same interface
- Discoverability: Third-party plugins can be discovered automatically
- Type Safety: Protocol ensures type safety with static type checkers
4.2 Negative Impacts
- Complexity: Slightly more complex than direct function calls
- Performance: Small overhead from plugin discovery and registry lookups
- Learning Curve: Developers need to understand the plugin system
5 · Decision
We will implement the plugin architecture as described in Section 2, using:
- The
IngestorPlugin
Protocol for defining the plugin interface - The
IngestorRegistry
class for managing plugins - The entry point discovery mechanism for third-party plugins
- Integration with the build process to use all available plugins
This approach provides the best balance of flexibility, type safety, and ease of use.
Proposed – 2025-04-23
— Jarrod Barnes
6 · Implementation Checklist
- Create
plugins.py
module withIngestorPlugin
Protocol - Implement
IngestorRegistry
class - Add plugin discovery function
- Refactor existing ingestors to implement the Protocol:
- Convert
ingest_git.py
toGitIngestor
class - Convert
ingest_github.py
toGitHubIngestor
class - Convert
ingest_adr.py
toADRIngestor
class
- Convert
- Update build process to use the plugin registry
- Add tests for the plugin system
- Create documentation for plugin developers
- Create example plugin for reference