Skip to content

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

for scenario in loader:
    print(f"{scenario['id']}: {scenario['name']} ({scenario['type']})")

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.