Plugin Boundaries¶
The FCC framework supports 11 plugin types, each declared as an ABC under
src/fcc/plugins/base.py (with two — EventSubscriberPlugin and
VocabularyProviderPlugin — living in their respective subsystem modules).
This page is the reference for plugin authors: per type, the contract you
must implement, the lifecycle hook the framework will call, and a minimal
working example.
The capability map below shows where each plugin type plugs into the framework's load path.
graph LR
subgraph DISC["Discovery"]
REG["PluginRegistry<br/>(plugins/registry.py)"]
EP[entry_points group<br/>fcc.plugins.*]
end
subgraph TYPES["11 plugin types"]
PE[PersonaPlugin]
EN[EnginePlugin]
TM[TemplatePlugin]
SC[ScorerPlugin]
VA[ValidatorPlugin]
PR[AIProviderPlugin]
GO[GovernancePlugin]
SN[ScenarioPlugin]
WF[WorkflowPlugin]
SU[EventSubscriberPlugin]
VP[VocabularyProviderPlugin]
end
subgraph CONS["Consumers in src/fcc/"]
C_REG[personas/registry.py]
C_SIM[simulation/engine.py]
C_DG[scaffold/doc_generator.py]
C_SCO[collaboration/scoring.py]
C_VAL[compliance/pipeline.py]
C_AI[simulation/ai_client.py]
C_GOV[governance/]
C_SC[scenarios/loader.py]
C_WF[workflow/loader.py]
C_BUS[messaging/bus.py]
C_VOC[objectmodel/vocabulary_loader.py]
end
EP --> REG
REG --> PE
REG --> EN
REG --> TM
REG --> SC
REG --> VA
REG --> PR
REG --> GO
REG --> SN
REG --> WF
REG --> SU
REG --> VP
PE --> C_REG
EN --> C_SIM
TM --> C_DG
SC --> C_SCO
VA --> C_VAL
PR --> C_AI
GO --> C_GOV
SN --> C_SC
WF --> C_WF
SU --> C_BUS
VP --> C_VOC
The pattern across all 11 types is the same: an ABC with a plugin_meta()
classmethod that returns a PluginMeta frozen dataclass, plus type-specific
hooks. The framework discovers plugins through Python entry points; nothing
else is required at install time.
The PluginMeta contract¶
Every plugin must return a PluginMeta from plugin_meta():
@dataclass(frozen=True)
class PluginMeta:
id: str # globally-unique plugin id, kebab-case
name: str # human-readable label
version: str # SemVer
plugin_type: PluginType
description: str
author: str
source_package: str # the importable package name
tags: tuple[str, ...]
plugin_type must match the ABC the plugin extends. The registry rejects
mismatches at discovery time.
The 11 plugin types¶
1. PersonaPlugin¶
Consumer: src/fcc/personas/registry.py (PersonaRegistry merges plugin
personas into the core registry).
Methods:
plugin_meta() -> PluginMetaget_persona_paths() -> list[Path]— YAML files defining personasget_dimension_paths() -> list[Path]— optional dimension-profile YAMLsget_cross_reference_paths() -> list[Path]— optional matrix YAMLs
Used by: vocabulary-provider plugins from sister projects (PAOM, AOME, CTO) that bundle their own persona libraries.
2. EnginePlugin¶
Consumer: src/fcc/simulation/engine.py (SimulationEngine selects
between mock + AI + plugin-supplied engines).
Methods:
plugin_meta() -> PluginMetaget_engine_class() -> type— must implement theEngineProtocol
Used by: experimental engine swaps (e.g. trace-replay engine for testing).
3. TemplatePlugin¶
Consumer: src/fcc/scaffold/doc_generator.py (DocGenerator stacks
plugin template dirs over the core template set).
Methods:
plugin_meta() -> PluginMetaget_template_dirs() -> list[Path]— Jinja2 template roots
Used by: vertical-pack plugins that need custom docs-as-code templates (e.g. healthcare HIPAA section in compliance reports).
4. ScorerPlugin¶
Consumer: src/fcc/collaboration/scoring.py (ScoringEngine routes
deliverables through registered scorers).
Methods:
plugin_meta() -> PluginMetaget_scorers() -> dict[str, Any]— name → scorer callable
Used by: domain-specific quality scorers (e.g. clinical-relevance
scorer for medical content).
5. ValidatorPlugin¶
Consumer: src/fcc/compliance/pipeline.py (CompliancePipeline runs
each rule against generated artifacts).
Methods:
plugin_meta() -> PluginMetaget_validation_rules() -> dict[str, Any]— rule name → callable
Used by: regulatory packs (HIPAA, SOX, GDPR) that ship rule libraries.
6. AIProviderPlugin¶
Consumer: src/fcc/simulation/ai_client.py (BaseAIClient picks
provider via auto-detection or scenario override).
Methods:
plugin_meta() -> PluginMetaget_provider_id() -> str— e.g."ollama"get_client_class() -> type— implementsBaseAIClientget_default_model() -> strget_env_var_hint() -> str | None— name of env var that, if set, signals "use me"
Used by: built-ins (anthropic, openai, azure_openai), v1.1.0 plugins (ollama, litellm), v1.1.1 plugin (vLLM).
Auto-detection: if get_env_var_hint() returns "OLLAMA_BASE_URL" and
that var is set, the provider is auto-selected.
7. GovernancePlugin¶
Consumer: src/fcc/governance/ (TagRegistry + QualityGateRegistry
merge plugin contributions).
Methods:
plugin_meta() -> PluginMetaget_tag_paths() -> list[Path]— additional tag-registry YAMLsget_quality_gate_paths() -> list[Path]— additional gate YAMLs
Used by: regulatory packs (e.g. an NIST gate set).
8. ScenarioPlugin¶
Consumer: src/fcc/scenarios/loader.py (ScenarioLoader concatenates
plugin scenarios with built-ins).
Methods:
plugin_meta() -> PluginMetaget_scenario_paths() -> list[Path]— scenario JSON/YAML files
Used by: vertical packs that bundle domain scenarios.
9. WorkflowPlugin¶
Consumer: src/fcc/workflow/loader.py (WorkflowGraph registry).
Methods:
plugin_meta() -> PluginMetaget_workflow_paths() -> list[Path]— workflow graph JSONs
Used by: rare — most teams reuse the 7 built-in graphs (5-node base, 20-node extended, 24-node complete, 55-node extended_84, 2 EAIFC).
10. EventSubscriberPlugin¶
Consumer: src/fcc/messaging/plugin_bridge.py →
src/fcc/messaging/bus.py (EventBus).
Methods:
plugin_meta() -> PluginMetaget_subscribers() -> list[tuple[Subscriber, EventFilter | None]]— pairs of (callable, optional filter)
Used by: ComplianceSubscriber (auto re-audit on persona change), external observability bridges, custom alerting.
11. VocabularyProviderPlugin¶
Consumer: src/fcc/objectmodel/vocabulary_loader.py
(VocabularyMappingLoader verifies sister-project vocab against FCC's 175
packaged YAML mappings).
Methods:
plugin_meta() -> PluginMetaget_namespace() -> str— e.g."athenium","libra"get_class_map() -> dict[str, type]— local-id → dataclass type
Used by: 12 plugins shipped as of v1.3.0 — fcc-athenium-plugin,
fcc-mnemosyne-plugin, plus 10 constellation packs (Caelum, Columba,
Crater, Libra, Norma, Ophiuchus, Pyxis, Scutum, Serpens, Vela). Sister
projects remain pure-data dataclass libraries with no FCC dependency; the
plugin packages live under FCC's plugins/ directory.
Discovery + lifecycle¶
The plugin discovery sequence is the same for every type:
- install time — plugin package declares an
entry_pointsblock in itspyproject.tomlunder the matching group (e.g.fcc.plugins.vocabulary_providers). - first call to
PluginRegistry.discover(plugin_type)— the registry enumerates entry points, instantiates each, callsplugin_meta(), verifies the type, caches the instance. - subsystem use — the consumer subsystem (e.g. PersonaRegistry) calls
the type-specific methods (
get_persona_paths()) and merges results. - event emission — each successful load emits a
plugin.loadedevent; each failure emitsplugin.failedwith the traceback.
There is no eager import — a plugin that fails to import is logged but does not crash the framework.
Minimal example: an EventSubscriberPlugin¶
from fcc.messaging import EventBus, EventFilter, EventType
from fcc.messaging.plugin_bridge import EventSubscriberPlugin
from fcc.plugins.base import PluginMeta, PluginType
class AuditLogPlugin(EventSubscriberPlugin):
@classmethod
def plugin_meta(cls) -> PluginMeta:
return PluginMeta(
id="example-audit-log",
name="Audit Log",
version="0.1.0",
plugin_type=PluginType.SUBSCRIBERS,
description="Append every workflow event to disk.",
author="example.com",
source_package="example_audit_log",
tags=("audit", "observability"),
)
def get_subscribers(self):
def write(evt):
with open("audit.log", "a") as f:
f.write(f"{evt.timestamp} {evt.event_type.value} {evt.source}\n")
return [(write, EventFilter(event_types={EventType.WORKFLOW_STEP}))]
pyproject.toml:
After pip install ./example-audit-log, PluginRegistry.discover() picks
it up and the EventBus calls write on every WORKFLOW_STEP event.
See also¶
- Source:
src/fcc/plugins/base.py,src/fcc/plugins/registry.py - Class diagram: plugin hierarchy
- Sequence diagram: vocabulary-provider load
- Sequence diagram: event-bus pub/sub