Scenarios API¶
The fcc.scenarios package provides a scenario loading system and a
rule-based validation framework for verifying FCC simulation outputs.
flowchart LR
JSON[Scenario JSON Files] --> SL[ScenarioLoader]
SL -->|from_directory| Merge[Merge & Dedupe]
Merge --> Scenarios[Scenario Registry]
Scenarios --> FV[FCCValidator]
SIM[Simulation Result] --> FV
FV --> R1[validate_artifact_completeness]
FV --> R2[validate_fcc_cycle]
FV --> R3[validate_quality]
R1 --> VR[ValidationResult list]
R2 --> VR
R3 --> VR
ScenarioLoader¶
ScenarioLoader reads scenario definitions from JSON files and provides
query methods to filter and retrieve them.
Loading from a Single File¶
from fcc._resources import get_scenarios_dir
from fcc.scenarios.loader import ScenarioLoader
loader = ScenarioLoader(get_scenarios_dir() / "starter_scenarios.json")
print(f"Total scenarios: {len(loader)}")
print(f"Scenario IDs: {loader.ids()}")
Loading from a Directory¶
When you have multiple scenario files, load them all at once. Scenarios are merged with deduplication by ID.
from fcc._resources import get_scenarios_dir
from fcc.scenarios.loader import ScenarioLoader
loader = ScenarioLoader.from_directory(get_scenarios_dir())
print(f"Total scenarios: {len(loader)}")
Loading from Explicit Files¶
from fcc._resources import get_scenarios_dir
from fcc.scenarios.loader import ScenarioLoader
loader = ScenarioLoader.from_files(
get_scenarios_dir() / "starter_scenarios.json",
get_scenarios_dir() / "edge_case_scenarios.json",
)
Querying Scenarios¶
from fcc._resources import get_scenarios_dir
from fcc.scenarios.loader import ScenarioLoader
loader = ScenarioLoader.from_directory(get_scenarios_dir())
# Get a specific scenario by ID
scenario = loader.get("GEN-001")
if scenario:
print(f"Name: {scenario['name']}")
print(f"Type: {scenario['type']}")
# Filter by type
typical = loader.by_type("typical")
edge_cases = loader.by_type("edge_case")
ai_scenarios = loader.by_type("ai")
print(f"Typical: {len(typical)}, Edge: {len(edge_cases)}, AI: {len(ai_scenarios)}")
Iterating Over Scenarios¶
Merging Loaders¶
from fcc.scenarios.loader import ScenarioLoader
base_loader = ScenarioLoader(get_scenarios_dir() / "starter_scenarios.json")
extra_loader = ScenarioLoader(get_scenarios_dir() / "edge_case_scenarios.json")
combined = base_loader.merge(extra_loader)
print(f"Combined: {len(combined)} scenarios (deduped by ID)")
Scenario JSON Format¶
Each JSON file contains a scenarios array. A scenario object typically has:
{
"scenarios": [
{
"id": "GEN-001",
"name": "General documentation generation",
"type": "typical",
"setup": {
"start_node": "RC",
"expected_artifacts": ["research_inventory", "blueprint", "runbook"],
"max_steps": 100
},
"validation_rules": [
{"rule": "artifact_completeness"},
{"rule": "full_fcc_cycle"},
{"rule": "traceability_chain"},
{"rule": "quality_threshold", "threshold": 0.80}
]
}
]
}
FCCValidator¶
The validator runs rule-based checks against simulation results. It ships with 9 built-in rules covering artifact completeness, FCC cycle coverage, traceability, quality thresholds, champion orchestration, cross-category coverage, governance gates, feedback loop termination, and stakeholder notification.
Creating a Validator¶
from fcc.scenarios.validators import FCCValidator
# Default validator with hard-coded FCC phase mapping
validator = FCCValidator()
Creating from a PersonaRegistry (Dynamic Mapping)¶
When you have a full registry, from_registry builds the FCC phase mapping
dynamically so that custom personas are automatically included.
from fcc._resources import get_personas_dir
from fcc.personas.registry import PersonaRegistry
from fcc.scenarios.validators import FCCValidator
registry = PersonaRegistry.from_yaml_directory(get_personas_dir())
validator = FCCValidator.from_registry(registry)
Individual Validation Methods¶
Each validation method returns a ValidationResult with passed, severity,
message, and details fields.
from fcc.scenarios.validators import FCCValidator
validator = FCCValidator()
# 1. Artifact completeness
result = validator.validate_artifact_completeness(
expected=["research_inventory", "blueprint", "runbook"],
actual=["research_inventory", "blueprint"],
threshold=0.90,
)
print(f"Passed: {result.passed}, Message: {result.message}")
# 2. Traceability chain
result = validator.validate_traceability({
"scenario_id": "GEN-001",
"personas": ["RC", "BC", "DE"],
})
print(f"Passed: {result.passed}")
# 3. Full FCC cycle
result = validator.validate_fcc_cycle(
personas=["Research Crafter", "Blueprint Crafter", "Documentation Evangelist"],
min_personas=3,
)
print(f"FCC phases covered: {result.details['phases_covered']}")
# 4. Quality threshold
result = validator.validate_quality(actual=0.85, threshold=0.80)
print(f"Passed: {result.passed}")
# 5. Champion orchestration
result = validator.validate_champion_orchestration(
champion_id="RCHM",
orchestrated_personas=["RC", "CIA", "RIC"],
personas_executed=["RC", "CIA", "RIC", "DE"],
)
print(f"Passed: {result.passed}")
# 6. Cross-category coverage
result = validator.validate_cross_category_coverage(
personas_executed=["RC", "CIA", "DGS"],
min_categories=2,
)
print(f"Categories: {result.details['categories']}")
# 7. Governance gate
result = validator.validate_governance_gate(
personas_executed=["RC", "BC", "DGS"],
)
print(f"Governance personas: {result.details['governance_executed']}")
# 8. Feedback loop termination
result = validator.validate_feedback_loop_termination(
steps_taken=45,
max_steps=100,
)
print(f"Converged: {result.passed}")
# 9. Stakeholder notification
result = validator.validate_stakeholder_notification(
personas_executed=["RC", "BC", "CO"],
)
print(f"Stakeholders: {result.details['stakeholders_executed']}")
Running All Validations for a Scenario¶
The validate_scenario method matches each rule in the scenario's
validation_rules list to the appropriate validation method and returns
a list of ValidationResult objects.
from fcc.scenarios.validators import FCCValidator
validator = FCCValidator()
scenario = {
"id": "GEN-001",
"name": "General doc generation",
"setup": {
"expected_artifacts": ["research_inventory", "blueprint"],
"max_steps": 100,
},
"validation_rules": [
{"rule": "artifact_completeness"},
{"rule": "full_fcc_cycle"},
{"rule": "quality_threshold", "threshold": 0.80},
{"rule": "feedback_loop_termination"},
],
}
simulation_result = {
"artifacts": [
{"artifact_type": "research_inventory"},
{"artifact_type": "blueprint"},
],
"personas_executed": [
{"persona": "Research Crafter"},
{"persona": "Blueprint Crafter"},
{"persona": "Documentation Evangelist"},
],
"quality_score": 0.92,
"steps_taken": 45,
}
results = validator.validate_scenario(scenario, simulation_result)
for r in results:
status = "PASS" if r.passed else "FAIL"
print(f" [{status}] {r.rule}: {r.message}")
ValidationResult and ValidationSeverity¶
from fcc.scenarios.models import ValidationResult, ValidationSeverity
result = ValidationResult(
rule="artifact_completeness",
passed=True,
severity=ValidationSeverity.INFO,
message="All artifacts generated",
details={"completeness": 1.0},
)
print(result.to_dict())
# {'rule': 'artifact_completeness', 'passed': True, 'severity': 'info', 'message': 'All artifacts generated'}
Severity levels: INFO, WARNING, ERROR, CRITICAL.