Energy vertical — professional tutorial¶
Released in FCC v1.2.0. You are integrating FCC into a production Energy workflow with real compliance obligations. This tutorial covers the EU AI Act risk classification path, the vertical_risk_profiles override layer, and how to wire a persona into an existing event-bus + observability stack.
The Energy pack in one paragraph¶
The energy vertical pack (at src/fcc/data/verticals/energy.yaml) contains 6 personas covering grid model management (IEC 61970 CIM), energy settlements, NERC CIP compliance, demand response planning, renewable integration, and battery storage optimization. Headline compliance frameworks: IEC 61970 CIM, NERC CIP-003 through CIP-014, FERC Order 2222, IEEE 1547.
Focus persona: NCP — NERC CIP Compliance Officer¶
We'll anchor this tutorial on NCP, because it's the one most relevant to the professional audience in the Energy domain.
from fcc.verticals.registry import VerticalRegistry
reg = VerticalRegistry.from_builtin()
pack = reg.get("energy")
persona = next(p for p in pack.personas if p.id == "NCP")
print(persona.name)
print(persona.risk_category or "minimal")
riscear = persona.riscear or {}
print("Archetype:", riscear.get("archetype"))
print("Role:", riscear.get("role"))
Wiring NCP into a production pipeline¶
Production FCC deployments typically have three concerns when adopting a vertical persona: (1) risk classification, (2) event-bus integration, (3) observability.
1. Risk classification¶
Use the vertical_risk_profiles.yaml override path so risk categories are data-driven rather than inferred from role descriptions:
from fcc.compliance.classifier import AIActClassifier
classifier = AIActClassifier()
persona = pack.get_persona("NCP") if hasattr(pack, "get_persona") else next(p for p in pack.personas if p.id == "NCP")
# Must supply the vertical_domain so the override activates:
risk = classifier.classify_persona(persona, vertical_domain="energy")
If you disagree with the shipped classification, override it in your own
vertical_risk_profiles.yaml placed earlier on the import path — the file
is a plain YAML dict, trivial to fork.
2. Event-bus integration¶
Subscribe to persona.action.completed events filtered by the NCP ID:
from fcc.messaging.bus import EventBus
from fcc.messaging.events import EventType
bus = EventBus()
bus.subscribe_filter(
event_types={EventType.ACTION_COMPLETED},
filter_fn=lambda e: e.payload.get("persona_id") == "NCP",
handler=lambda e: audit_log.append(e),
)
3. Observability¶
Add a traced span around every NCP action so you can trace latency through OpenTelemetry:
from fcc.observability.tracing import get_tracer
tracer = get_tracer("fcc.energy")
with tracer.span(f"NCP.run", attributes={"domain": "energy"}):
result = action_engine.run(persona_id="NCP", ...)
Production checklist¶
- Risk category override present in
vertical_risk_profiles.yaml. - Event-bus subscribers for audit trail.
- Observability spans + metrics exporters configured.
- CI runs
pytest tests/test_verticals.py tests/test_compliance_classifier.py. - Model cards regenerated and committed (
fcc model-card generate --all).
Verify what you did¶
Run the vertical test suite to make sure your changes didn't break anything:
All professional-path steps in this tutorial leave your working tree unchanged — the pack YAML is read-only from your perspective. The only state that accumulates is in _output/ (scenario run traces) and docs/model-cards/ (if you regenerated cards).
Next steps¶
- Notebook 26 — Vertical packs tour — same flow in an executable notebook.
- Notebook 27 — Vertical packs deep dive — longer walkthrough of healthcare as an exemplar.
- Guidebook ch25 — Industry verticals — full authoring guide for your own pack.
- Book 3 ch11 — Vertical packs at enterprise scale — architectural view.
- Streamlit vertical_explorer — interactive browser for all 6 packs.
- Research note for energy — cited standards sources behind the persona selection.