Skip to content

Running Your First Simulation

This tutorial walks you through installing the FCC framework, loading the persona registry, running a deterministic simulation with scenario GEN-001 (Full FCC Cycle), and examining the trace output.

Prerequisites

  • Python 3.10 or later
  • Git (for cloning the repository)

Step 1: Install the Framework

Clone the repository and install in development mode:

git clone https://github.com/rollingthunderfourtytwo-afk/l2_fcc_agent_team_ext.git
cd l2_fcc_agent_team_ext
make venv && source .venv/bin/activate
make install-dev

Alternatively, install directly with pip:

pip install -e .

Verify the installation:

import fcc
print(fcc.__version__)

Step 2: Load the Persona Registry

The persona registry loads all 24 personas from the YAML files in data/personas/:

from pathlib import Path
from fcc.personas.registry import PersonaRegistry

data_dir = Path("data/personas")
registry = PersonaRegistry.from_yaml_directory(data_dir)

print(f"Loaded {len(registry)} personas")
print(f"IDs: {registry.ids}")

Expected output:

Loaded 24 personas
IDs: ['RC', 'BC', 'DE', 'RB', 'UG', 'CIA', 'UMC', 'STE', 'TS', 'BV', 'RIC', 'GCA', 'DGS', 'PTE', 'AMS', 'CO', 'SMC', 'EC', 'RS', 'SCP', 'RCHM', 'BCHM', 'UGCH', 'RBCH']

Inspect a specific persona:

rc = registry.get("RC")
print(f"Name: {rc.name}")
print(f"Phase: {rc.fcc_phase}")
print(f"Archetype: {rc.riscear.archetype}")
print(f"Inputs: {rc.riscear.inputs}")

Step 3: Load a Workflow Graph

Load the base workflow graph (5 nodes, 11 edges):

from fcc.workflow.graph import WorkflowGraph

graph = WorkflowGraph.from_json("data/workflows/base_sequence.json")

print(f"Title: {graph.meta.title}")
print(f"Nodes: {len(graph)} ({graph.node_ids})")
print(f"Edges: {len(graph.edges)}")
print(f"Handoffs: {len(graph.handoffs())}")
print(f"Feedbacks: {len(graph.feedbacks())}")

Expected output:

Title: FCC Personas Collaboration - Base Sequence
Nodes: 5 (['RC', 'BC', 'DE', 'RB', 'UG'])
Edges: 11
Handoffs: 7
Feedbacks: 4

Step 4: Load Scenario GEN-001

Load the starter scenarios and select GEN-001 (Full FCC Cycle):

from fcc.scenarios.loader import ScenarioLoader

loader = ScenarioLoader("data/scenarios/starter_scenarios.json")
scenario = loader.get("GEN-001")

print(f"Scenario: {scenario['name']}")
print(f"Description: {scenario['description']}")
print(f"Start node: {scenario['setup']['start_node']}")
print(f"Initial input: {scenario['setup']['initial_input']}")
print(f"Personas: {scenario['setup']['personas_involved']}")
print(f"Max steps: {scenario['setup']['max_steps']}")

Expected output:

Scenario: Full FCC Cycle
Description: Complete Find->Create->Critique cycle through all 5 personas (RC->BC->DE->RB->UG)
Start node: RC
Initial input: Research and document a new microservice API
Personas: ['Research Crafter', 'Blueprint Crafter', 'Documentation Evangelist', 'Runbook Crafter', 'User Guide Crafter']
Max steps: 50

Step 5: Run the Simulation

Create a SimulationEngine and run the deterministic simulation:

from fcc.simulation.engine import SimulationEngine

engine = SimulationEngine(
    graph=graph,
    max_steps=scenario["setup"]["max_steps"],
    max_history=16,
)

history = engine.run(
    start_node=scenario["setup"]["start_node"],
    initial_payload=scenario["setup"]["initial_input"],
)

print(f"Events recorded: {len(history.events)}")

The deterministic engine uses BFS message passing: it starts at the start_node, processes the initial message, then propagates new messages along all outgoing edges. Each propagation creates a new event in the history.

Step 6: Examine the Trace Output

Look at the first few events:

for event in history.events[:5]:
    print(f"Step {event['step']}: {event['actor']}")
    print(f"  Payload: {event['payload'][:80]}...")
    print(f"  Edge: {event['edge_label']}")
    print(f"  History length: {event['history_len']}")
    print()

Expected output pattern:

Step 1: Research Crafter
  Payload: Research and document a new microservice API...
  Edge: initial
  History length: 1

Step 2: Blueprint Crafter
  Payload: Research and document a new microservice API -> research_inventory...
  Edge: research_inventory
  History length: 2

Step 3: Documentation Evangelist
  Payload: Research and document a new microservice API -> research_inventory -> blu...
  Edge: blueprints_specs
  History length: 3

Each event records:

  • step: Sequential step number
  • actor: The persona that processed the message
  • payload: The accumulated message payload (grows with each edge traversal)
  • edge_label: The workflow edge that delivered this message
  • history_len: How many processing annotations the message has accumulated
  • history: Full list of processing annotations with timestamps

Step 7: Save the Trace

Save the trace output to a JSON file:

history_saved = engine.run_and_save(
    output_path="output/gen001_trace.json",
    start_node="RC",
    initial_payload="Research and document a new microservice API",
)

print("Trace saved to output/gen001_trace.json")

The saved file follows the traces schema (data/schemas/traces.schema.json) and contains:

{
  "generated_at": "2024-01-15T10:30:00+00:00",
  "events": [
    {
      "step": 1,
      "timestamp": "2024-01-15T10:30:00.001+00:00",
      "actor": "Research Crafter",
      "payload": "Research and document a new microservice API",
      "origin": "RC",
      "edge_label": "initial",
      "history_len": 1,
      "history": [
        {
          "actor": "Research Crafter",
          "note": "Research Crafter processed payload='Research and document a new microservice API'",
          "timestamp": "2024-01-15T10:30:00.001+00:00"
        }
      ]
    }
  ]
}

Step 8: Validate the Trace

Validate the saved trace against the JSON schema:

from fcc.simulation.traces import validate_traces

is_valid = validate_traces(
    "output/gen001_trace.json",
    "data/schemas/traces.schema.json",
)
print(f"Trace valid: {is_valid}")

What Just Happened

You ran a complete FCC cycle through all 5 core personas:

  1. RC (Find) received the initial research prompt
  2. BC (Create) received the research inventory and created blueprint specs
  3. DE (Critique) reviewed the blueprints and published handoffs
  4. RB (Create) received published specs and created runbook content
  5. UG (Create) received published specs and created user guide content
  6. Feedback edges sent operational findings and user feedback back to RC and BC
  7. The cycle continued until max_steps or max_history was reached

Next Steps