4+1 Logical View¶
The Logical View captures what FCC knows. Personas, workflows, plugins, events, and governance data form the core of the logical model. This page is the first of Philippe Kruchten's 4+1 views; it complements the Process View (runtime), the Development View (packaging), the Physical View (deployment), and the Scenarios View (+1) that validates all four against concrete use cases.
The three diagrams below focus on the three most load-bearing static structures in the framework: the persona model, the plugin taxonomy, and the compliance + governance stack.
Core persona and workflow model¶
The primary logical abstraction is the PersonaSpec frozen dataclass.
Every agent in the 147-persona catalog is an instance of PersonaSpec,
aggregating a RISCEARSpec contract, a six-trait discernment matrix, a
six-factor design-target profile, and an optional 56-dimension profile.
Workflows reference personas by ID via WorkflowNode entries; the
ActionEngine consumes both a PersonaSpec and a WorkflowAction when
it renders a prompt for the simulation layer.
Figure 1 shows the composition between PersonaSpec, RISCEARSpec,
PersonaRegistry, WorkflowGraph, WorkflowAction, and ActionEngine.
classDiagram
class PersonaSpec {
<<frozen dataclass>>
+id : str
+name : str
+fcc_phase : str
+category : str
+champion_of : str | None
+orchestrates : list[str]
+doc_context : dict | None
}
class RISCEARSpec {
<<frozen dataclass>>
+role : str
+inputs : list[str]
+style : str
+constraints : list[str]
+expected_output : str
+archetype : str
+responsibilities : list[str]
+role_skills : list[str]
+role_collaborators : list[str]
+role_adoption_checklist : list[str]
}
class PersonaRegistry {
+load_directory(path) PersonaRegistry
+by_id(id) PersonaSpec
+by_category(cat) list~PersonaSpec~
+champions() list~PersonaSpec~
+merge(other) PersonaRegistry
}
class WorkflowGraph {
+nodes : dict
+edges : list
+start_node : str
+load_json(path) WorkflowGraph
+get_node(id) WorkflowNode
}
class WorkflowNode {
+id : str
+persona_id : str
+action_id : str
}
class WorkflowAction {
+id : str
+action_type : WorkflowActionType
+expected_output : str
+prompt_template : str
}
class ActionEngine {
+registry : WorkflowActionRegistry
+run(persona, action, payload) ActionResult
+get_action_prompt(persona, action) tuple
}
PersonaSpec "1" *-- "1" RISCEARSpec : riscear
PersonaRegistry "1" o-- "many" PersonaSpec : stores
WorkflowGraph "1" *-- "many" WorkflowNode : nodes
WorkflowNode "1" ..> "1" WorkflowAction : references
WorkflowNode "1" ..> "1" PersonaSpec : references
ActionEngine "1" ..> "1" PersonaSpec : consumes
ActionEngine "1" ..> "1" WorkflowAction : consumes
The flat composition keeps serialisation symmetric and the loader stateless.
Plugin taxonomy¶
FCC's extensibility surface is 11 plugin types, each an abstract base
class under src/fcc/plugins/base.py. At import time the
PluginRegistry discovers concrete plugins through setuptools entry
points; every plugin participates in a uniform lifecycle (name(),
version(), initialize(), teardown()).
Figure 2 is a PlantUML class diagram of the 11-type plugin taxonomy and their shared interface.
@startuml
abstract class FCCPlugin {
+name() : str
+version() : str
+initialize(ctx) : None
+teardown() : None
}
class PersonaPlugin
class EnginePlugin
class TemplatePlugin
class ScorerPlugin
class ValidatorPlugin
class AIProviderPlugin {
+get_env_var_hint() : str
+build_client(cfg) : BaseAIClient
}
class GovernancePlugin
class ScenarioPlugin
class WorkflowPlugin
class EventSubscriberPlugin {
+subscribe(bus) : None
}
class VocabularyProviderPlugin {
+provides() : list
+load_mappings() : list
}
FCCPlugin <|-- PersonaPlugin
FCCPlugin <|-- EnginePlugin
FCCPlugin <|-- TemplatePlugin
FCCPlugin <|-- ScorerPlugin
FCCPlugin <|-- ValidatorPlugin
FCCPlugin <|-- AIProviderPlugin
FCCPlugin <|-- GovernancePlugin
FCCPlugin <|-- ScenarioPlugin
FCCPlugin <|-- WorkflowPlugin
FCCPlugin <|-- EventSubscriberPlugin
FCCPlugin <|-- VocabularyProviderPlugin
@enduml
VocabularyProviderPlugin (v1.2.1+) is the newest member and the primary seam for cross-project entity resolution.
Compliance and governance¶
FCC v1.3.x ships an EU AI Act + NIST AI RMF compliance pipeline on top
of 58 quality gates. The compliance model is a pure-data stack that the
ComplianceAuditor walks per persona.
Figure 3 shows the core compliance classes and their relationship to the governance constitution registry.
classDiagram
class ComplianceAuditor {
+registry : RequirementRegistry
+classifier : AIActClassifier
+audit(persona_registry) ComplianceReport
}
class RequirementRegistry {
+requirements : dict
+load() RequirementRegistry
+by_category(cat) list
}
class AIActClassifier {
+classify(persona) RiskCategory
}
class ComplianceRequirement {
<<frozen dataclass>>
+id : str
+regulation : str
+article : str
+risk_category : RiskCategory
+description : str
}
class QualityGate {
<<frozen dataclass>>
+id : str
+severity : str
+persona_scope : list
+check_fn : str
}
class ConstitutionRegistry {
+lookup(persona_id) PersonaConstitution
+tiers() list
}
class PersonaConstitution {
+hard_stops : list
+mandatory : list
+preferred : list
}
ComplianceAuditor "1" o-- "1" RequirementRegistry : uses
ComplianceAuditor "1" o-- "1" AIActClassifier : uses
RequirementRegistry "1" *-- "many" ComplianceRequirement
ConstitutionRegistry "1" *-- "many" PersonaConstitution
ComplianceAuditor "1" ..> "many" QualityGate : evaluates
ComplianceAuditor "1" ..> "1" ConstitutionRegistry : consults
How the pieces interact¶
At load time the CLI builds a PersonaRegistry from
src/fcc/personas/registry.py:62, a WorkflowActionRegistry from the
312 action YAML files under src/fcc/data/personas/actions/, and seven
WorkflowGraph instances from src/fcc/data/workflows/. The
ActionEngine at src/fcc/workflow/action_engine.py:51 is the pure
function that turns a (PersonaSpec, WorkflowAction) pair into a
renderable prompt; it holds no mutable state. The simulation layer
aggregates these, publishes events, and records turns.
The compliance path is structurally parallel: ComplianceAuditor at
src/fcc/compliance/auditor.py:28 pulls personas from the same
PersonaRegistry, classifies each against EU AI Act risk tiers via
AIActClassifier at src/fcc/compliance/classifier.py:19, and emits a
ComplianceReport that the dashboard and evidence-graph builders can
consume without needing to re-load anything.
The three diagrams above show three views of the same intuition: FCC's data is all frozen dataclasses, its registries are plain collections, and its engines are stateless transformers. That uniformity is what keeps the docs-as-code generator, the model-card pipeline, and the evidence-graph builder deterministic.
See also¶
src/fcc/personas/models.py:104(RISCEARSpec),src/fcc/personas/models.py:168(PersonaSpec)src/fcc/workflow/graph.py(WorkflowGraph,WorkflowNode)src/fcc/workflow/action_engine.py:51(ActionEngine.run)src/fcc/compliance/auditor.py:28(ComplianceAuditor.audit)src/fcc/plugins/base.py(11 plugin ABCs)- Process View
- Class diagrams deep-dive
v1.5.0 Logical Impact¶
v1.5.0 added five new first-class modules to the Logical View without
disturbing any existing class. Each addition landed behind a stable
fcc.api.* re-export so the Logical View now has two layers: the
original pure-data aggregates (persona / workflow / compliance) and the
new capability bridges (archive, knowledge, rag.graphrag,
collaboration.crdt, collaboration.multi_user, federation.bidirectional).
| Module | Key classes | Anchor diagram |
|---|---|---|
src/fcc/rag/graphrag.py |
GraphRAG, GraphRAGResult, assemble_context, retriever_from_graph |
../sequence-diagrams/graphrag-zachman-filter.md |
src/fcc/collaboration/crdt.py |
CRDTBackend (Protocol), InMemoryBackend, YPyBackend, CollaborativeDocument, _LwwOp, _PresenceEntry, get_crdt_backend |
../sequence-diagrams/crdt-multi-user-merge.md |
src/fcc/collaboration/multi_user.py |
MultiUserSession, MultiUserEngine, Edit, EditKind, PresenceInfo, envelope helpers |
../use-case-diagrams/multi-user-session.md |
src/fcc/federation/bidirectional.py |
BidirectionalSync, Conflict, SyncReport, Resolution enum |
../sequence-diagrams/bidirectional-federation-sync.md |
src/fcc/archive/polaris_bridge.py |
re-exports: PolarisBridgeProtocol, PolarisMockBridge, NoOpPolarisBridge, get_polaris_bridge |
../class-diagrams/polaris-bridge.md |
src/fcc/knowledge/lyra_bridge.py |
re-exports: LyraBridgeProtocol, LyraMockBridge, NoOpLyraBridge, get_lyra_bridge |
../class-diagrams/lyra-bridge.md |
Three structural observations for the Logical View. First, every
addition keeps the "frozen dataclasses + plain registries + stateless
engines" shape the view codified — GraphRAGResult, Conflict,
SyncReport, PresenceInfo, and Edit are all frozen dataclasses.
Second, two new Protocols (CRDTBackend, PolarisBridgeProtocol,
LyraBridgeProtocol) extend the plugin taxonomy's structural-typing
idiom without adding new plugin types. Third, the fcc.api.* re-export
layer is the new public promotion contract — the old single-import
paths still work through v1.5.x with a DeprecationWarning and go
away in v1.6.0. See ../class-diagrams/six-pillars-overview.md for
the full module map and ADR-006..013 for the decision trail.
v1.6.0 Impact¶
v1.6.0 executed three of the six pillars that v1.5.0 introduced — A (seed data), C (i18n translation), and the live half of B's LYRA bridge — without adding a new top-level subpackage. The Logical View therefore grows new modules inside existing subpackages plus new script-level helpers that are not part of the Python import graph but are part of the logical architecture of the publishable deliverable.
| Module / artifact | Key classes / symbols | Role |
|---|---|---|
publications/scripts/seed_canonical.py |
CanonicalSource (frozen dataclass), SUPPORTED_VERTICALS, seed_canonical(vertical, dry_run) |
Pillar A — intent + license registry (v1.5.0 scaffold, stable in v1.6.0) |
publications/scripts/fetch_canonical_seeds.py |
FileResult (frozen dataclass), fetch_all(accept_flag), _sha256, _record_manifest_entry |
Pillar A — owner-gated downloader; emits seed_canonical_manifest.json |
docs/i18n/glossary.csv + scripts/verify_glossary_preservation.py |
load_do_not_translate_terms, verify_locale(path) |
Pillar C — do-not-translate glossary enforcer (R.I.S.C.E.A.R., Zachman row/column names, persona IDs) |
frontend/src/i18n/locales/{en,fr,es,de}/common.json + config.ts |
i18n locale resolver + runtime language switch | Pillar C — React/i18next consumer of the translated strings |
src/fcc/knowledge/lyra_bridge.py → get_lyra_bridge() |
LyraAdapter resolution path (live branch), LyraMockBridge (fallback) |
Pillar B — live LYRA adapter resolution; sentinel-probed at call time |
scripts/verify_codename_decoder.py |
extract_table_rows, check_paths, check_placeholders |
Ecosystem docs — enforces that every codename in docs/ecosystem/codename-decoder.md resolves to a real local path or an explicit "not cloned locally" sentinel |
Three structural observations for v1.6.0. First, the seed-canonical
fetch pipeline is a Logical-View citizen even though it lives under
publications/scripts/ — it produces a committed artifact
(publications/_output/seed_canonical_manifest.json) that downstream
consumers (vertical plugins, tutorials, the test harness) treat as the
canonical corpus manifest; the SHA-256-keyed entries are a first-class
data contract. Second, the i18n locale resolver is a
runtime module on the frontend side and a build-time gate on the
Python side — the glossary preservation check runs in CI against the
four packaged common.json files and fails a release if any
do-not-translate term has been mutated. Third, the LYRA adapter
resolution is the only module whose behaviour changes in v1.6.0 even
though the source file did not move: get_lyra_bridge() continues to
probe lyra.api at call time, and the private lyra_ext repo is the
first environment where that probe returns True; LyraMockBridge
remains the default in unlocked environments.
The v1.5.x preview-path namespace (fcc.plugins.v1_5_preview.*) is
removed in v1.6.0 per the v1.5.0 migration notice; every caller
must now import through fcc.knowledge.lyra_bridge / fcc.archive.polaris_bridge
or the flat fcc.api re-export. See ADR-014 (render-pipeline Chromium
sandbox) for the v1.6.0 documentation-build story, and
../pillar-a-seed-lifecycle-v160.md, ../pillar-c-translation-flow-v160.md,
and ../lyra-live-integration-v160.md for the per-pillar diagrams.