## Status

Draft

## Story

**As a** system integrator,
**I want** a discoverable plugin registry using Python entry points,
**so that** plugins are automatically available after installation without manual wiring.

## Acceptance Criteria

1. Discovery uses v3 entry point groups per plugin type:
   - `fapilog.sinks`, `fapilog.processors`, `fapilog.enrichers`, `fapilog.redactors`, `fapilog.alerting`.
   - Optional fallback: support a generic `fapilog.plugins` group, deriving `plugin_type` from `PLUGIN_METADATA` when present.
2. Registry validates discovered plugins against both:
   - Fapilog core version compatibility (already implemented via `validate_fapilog_compatibility`).
   - Plugin API version compatibility (as defined in Story 1.15 with `api_version` and `PLUGIN_API_VERSION`).
3. Incompatible plugins are skipped with precise diagnostics via `core.diagnostics.warn` including: `plugin`, `reason`, `declared_api_version`, `expected_api_version` as applicable.
4. Configuration allows enabling/disabling by name and setting discovery paths:
   - Add a `PluginsSettings` group under `Settings` with fields: `enabled: bool = True`, `allowlist: list[str]`, `denylist: list[str]`, `load_on_startup: list[str]`, `discovery_paths: list[str]`.
   - Respect allow/deny lists during discovery/load; `load_on_startup` are eagerly loaded by `AsyncComponentRegistry.initialize()`.
5. Demonstrate discovery with at least one first-party plugin (e.g., rotating file sink) and ensure built-ins remain available even with no third-party installs.
6. Documentation for third-party authors: entry points, required `PLUGIN_METADATA` keys, and API versioning policy.

## Tasks / Subtasks

- [ ] Discovery alignment
  - [ ] Ensure `src/fapilog/plugins/discovery.py` enumerates per-type groups and also supports fallback `fapilog.plugins` group (AC: 1).
  - [ ] When using fallback group, derive `plugin_type` from `PLUGIN_METADATA["plugin_type"]` and validate consistency (AC: 1).
- [ ] Registry enforcement
  - [ ] In `src/fapilog/plugins/registry.py`, enforce API-version compatibility using utilities from Story 1.15 before instantiation (AC: 2).
  - [ ] Emit structured diagnostics via `core.diagnostics.warn` on incompatibility or load errors (AC: 3).
- [ ] Settings integration
  - [ ] Add `PluginsSettings` to `src/fapilog/core/settings.py` and a `plugins: PluginsSettings` field on `Settings` (AC: 4).
  - [ ] Update `AsyncComponentRegistry.initialize()` to respect `plugins.discovery_paths`, `allowlist`, `denylist`, and `load_on_startup` (AC: 4).
- [ ] Built-in demonstration
  - [ ] Update built-in `PLUGIN_METADATA` for sinks (`stdout_json`, `rotating_file`) to include `api_version: "1.0"` (AC: 5).
  - [ ] Verify built-ins are discoverable/usable with an empty third-party environment (AC: 5).
- [ ] Docs
  - [ ] Add `docs/plugins/authoring.md` describing: `pyproject.toml` entry points, `PLUGIN_METADATA` fields (`name`, `version`, `plugin_type`, `entry_point`, `compatibility`, `api_version`, optional `config_schema`/`default_config`), and the API versioning policy (AC: 6).

## Dev Notes

- Existing implementation:
  - Discovery: `src/fapilog/plugins/discovery.py` already supports per-type groups and local/PyPI scanning.
  - Registry: `src/fapilog/plugins/registry.py` handles load/registration and core-version compatibility.
  - Metadata: `src/fapilog/plugins/metadata.py` provides `PluginMetadata`, `PluginInfo`, and `validate_fapilog_compatibility`.
- Alignment with Story 1.15:
  - Extend metadata to include `api_version` and utilities for API compatibility if not already present.
  - Add API-version enforcement to registry load flow prior to instantiation.
- Settings design:
  - `PluginsSettings` fields should be Pydantic v2 with sensible defaults and docstrings.
  - Use `Settings().plugins` within discovery/registry wiring rather than global variables.
- Diagnostics:
  - Use `core.diagnostics.warn` for non-fatal issues; never crash discovery on errors.
- First-party example:
  - Built-ins can be tested via discovery without real entry points by mocking `importlib.metadata.entry_points()` in tests.

### Testing

- Locations:
  - Unit tests: `tests/unit/plugins/`
  - Integration tests: `tests/integration/plugins/`
- Unit tests:
  - Patch `importlib.metadata.entry_points` to provide fake groups and validate discovery per-type and fallback group.
  - Validate allowlist/denylist behavior and `load_on_startup` eager loading.
  - Assert API-version incompatible plugins are skipped with proper diagnostics.
- Integration tests:
  - Register a dummy plugin via temporary entry points or local discovery path and confirm load and lifecycle.
  - Verify behavior when no plugins are installed (built-ins still usable).
- Coverage: maintain >90% for new/modified paths.

## Change Log

| Date       | Version | Description                                                      | Author    |
| ---------- | ------- | ---------------------------------------------------------------- | --------- |
| 2025-08-15 | 0.2     | Align with existing discovery/registry; add settings and testing | Architect |

## Dev Agent Record

### Agent Model Used

{{agent_model_name_version}}

### Debug Log References

### Completion Notes List

### File List

## QA Results


