Skip to content

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