Skip to content

Action Workflow System

The FCC framework defines a 6-action system that describes what each persona can do, orthogonal to the graph-based workflow that describes when they act. Every persona can perform six action types: scaffold, refactor, debug, test, compare, and document. The system comprises 312 action definitions across 102 core personas.

The Six Action Types

Each action type has a specific purpose and preamble that guides the persona's behavior:

Action Type Purpose Preamble
scaffold Generate new artifacts from scratch Following best practices and governance requirements
refactor Improve and modernize existing artifacts Preserving correctness and meeting governance standards
debug Diagnose and fix issues Identifying root causes with prevention recommendations
test Validate quality against constraints Generating comprehensive test suites with edge-case coverage
compare Evaluate alternatives Analyzing trade-offs across performance, cost, and compliance
document Generate comprehensive documentation Including purpose, usage, architecture, and operational guidance

The action types are defined in the WorkflowActionType enum:

from fcc.workflow.actions import WorkflowActionType

# All six types in canonical order
all_types = WorkflowActionType.all_types()
# [SCAFFOLD, REFACTOR, DEBUG, TEST, COMPARE, DOCUMENT]

WorkflowAction

A WorkflowAction is a frozen dataclass describing what a specific persona does when performing a particular action type. It includes execution steps, constraints, inputs, outputs, and examples.

Field Type Description
persona_id str ID of the persona this action belongs to
action_type WorkflowActionType One of the six action types
description str What the persona does for this action
execution_steps tuple[str, ...] Ordered steps to execute the action
inputs tuple[str, ...] Required inputs for this action
outputs tuple[str, ...] Expected outputs from this action
constraints tuple[str, ...] Rules and limitations for this action
examples tuple[str, ...] Example usage scenarios

Actions are serializable to and from dictionaries and YAML:

from fcc.workflow.actions import WorkflowAction, WorkflowActionType

action = WorkflowAction(
    persona_id="SQC",
    action_type=WorkflowActionType.SCAFFOLD,
    description="Generate a new SQL query from requirements.",
    execution_steps=("Parse requirements", "Design schema", "Write query"),
    inputs=("Database schema", "Business requirements"),
    outputs=("SQL query file", "Query documentation"),
    constraints=("Must use parameterized queries",),
)

WorkflowActionRegistry

The WorkflowActionRegistry is the central store for all action definitions. It supports loading from YAML files, lookup by persona ID or action type, and schema-validated loading.

Loading Actions

from fcc.workflow.actions import WorkflowActionRegistry

# From a single YAML file
registry = WorkflowActionRegistry.from_yaml("actions/core.yaml")

# From a directory of YAML files
registry = WorkflowActionRegistry.from_yaml_directory("src/fcc/data/personas/actions/")

# With JSON Schema validation
registry = WorkflowActionRegistry.from_yaml_validated(
    "actions/core.yaml", "schemas/action_schema.json"
)

Querying Actions

from fcc.workflow.actions import WorkflowActionType

# Get a specific action
action = registry.get("SQC", WorkflowActionType.SCAFFOLD)

# Get all actions for a persona
actions = registry.for_persona("SQC")  # Returns list[WorkflowAction]

# Get all actions of a specific type across all personas
scaffold_actions = registry.for_type(WorkflowActionType.SCAFFOLD)

# Check if an action exists
exists = registry.has_action("SQC", WorkflowActionType.DEBUG)

# List all persona IDs with actions
persona_ids = registry.persona_ids  # sorted list of IDs

# List all registered action types
types = registry.action_types  # sorted list of WorkflowActionType

Mutating the Registry

# Add a single action
registry.add(new_action)

# Merge two registries into a new one
combined = registry1.merge(registry2)

# Export to YAML
registry.to_yaml("output/actions.yaml")

ActionEngine

The ActionEngine orchestrates execution of persona actions. It loads action definitions from the registry, builds persona-aware prompts incorporating R.I.S.C.E.A.R. specifications and constitution rules, and invokes an AI client for execution.

Initialization

from fcc.workflow.action_engine import ActionEngine

engine = ActionEngine(
    persona_registry=persona_registry,
    action_registry=action_registry,
    ai_client=ai_client,        # Optional; None = deterministic mock mode
    event_bus=event_bus,         # Optional; publishes action.started/completed/failed
)

Running an Action

from fcc.workflow.actions import WorkflowActionType

result = engine.run(
    persona_id="SQC",
    action_type=WorkflowActionType.SCAFFOLD,
    inputs={"query": "Find all active users", "database": "postgres"},
)

print(result.content)   # The generated output
print(result.success)   # True/False
print(result.error)     # Error message if failed
print(result.metadata)  # {"mode": "mock"} or {"mode": "ai", "model": "..."}

Mock vs. AI-Powered Mode

When no AI client is configured, the engine operates in deterministic mock mode, returning structured placeholder content. This is useful for testing workflows without incurring API costs.

When an AI client is provided, the engine builds two prompts:

  • System prompt: Persona identity (name, role, archetype, style), action context (preamble, description), R.I.S.C.E.A.R. constraints, expected outputs, and constitution rules (hard-stop and mandatory patterns).
  • User prompt: Execution steps, required inputs, expected outputs, and any user-provided inputs.

Prompt Generation

The get_action_prompt() function constructs persona-aware prompts by combining the persona's R.I.S.C.E.A.R. specification with the action definition:

from fcc.workflow.action_engine import get_action_prompt

prompts = get_action_prompt(persona, action)
# prompts["system"] — full persona identity + constraints + constitution
# prompts["user"]   — execution steps + inputs + outputs

The system prompt includes:

  1. Persona identity (name, ID, role title)
  2. R.I.S.C.E.A.R. role description
  3. Archetype and style
  4. Action type preamble and description
  5. R.I.S.C.E.A.R. constraints
  6. Action-specific constraints
  7. Expected outputs
  8. Constitution hard-stop and mandatory rules from doc_context

ActionResult

Every action execution returns an ActionResult dataclass:

Field Type Description
persona_id str The persona that performed the action
action_type WorkflowActionType The type of action performed
content str The generated output content
success bool Whether the action succeeded
error str | None Error message if the action failed
metadata dict[str, Any] Additional metadata (mode, model, tokens)

Event Bus Integration

When an EventBus is provided, the ActionEngine publishes events at key lifecycle points:

Event Type When Published
action.started Before action execution begins
action.completed After successful execution
action.failed When an error occurs during execution

Each event payload includes persona_id and action_type, plus mode-specific metadata.

YAML Action File Format

Action definitions are stored in YAML files under src/fcc/data/personas/actions/:

actions:
  - persona_id: SQC
    action_type: scaffold
    description: "Generate a new SQL query from requirements."
    execution_steps:
      - "Parse the business requirements"
      - "Identify required tables and relationships"
      - "Write the SQL query with parameterized inputs"
    inputs:
      - "Database schema documentation"
      - "Business requirements specification"
    outputs:
      - "SQL query file"
      - "Query documentation with usage examples"
    constraints:
      - "Must use parameterized queries to prevent SQL injection"
    examples:
      - "Generate a customer activity report query"