Skip to content

Creating Custom Personas

This tutorial walks you through creating a custom FCC persona: writing the YAML definition, registering it in the PersonaRegistry, validating against the JSON schema, and adding it to a workflow graph.

When to Create Custom Personas

Create a custom persona when your project needs a specialized role that is not covered by the 24 built-in personas. Common examples:

  • A domain-specific reviewer (e.g., security documentation specialist)
  • A team-specific content creator (e.g., API changelog writer)
  • An industry-specific compliance role (e.g., HIPAA documentation auditor)

Step 1: Write the YAML Definition

Create a new YAML file for your custom persona. The file must follow the same structure as the built-in persona files in data/personas/.

Here is a complete example of a custom Security Documentation Specialist:

personas:
  - id: SDS
    name: Security Documentation Specialist
    fcc_phase: Create
    role_title: Security Documentation Engineer
    color: "#B71C1C"
    category: integration
    riscear:
      role: >-
        Produces security-focused documentation including threat models,
        security architecture reviews, and compliance mapping documents.
        Ensures all documentation addresses security considerations and
        follows security documentation best practices.
      inputs:
        - Threat modeling outputs and risk assessments
        - Security architecture diagrams and data flow maps
        - Compliance requirements (SOC2, ISO 27001, NIST)
        - Penetration testing reports and vulnerability scans
      style: >-
        Security-focused, risk-aware, compliance-driven documentation.
        Uses structured threat analysis and control mapping formats.
      constraints:
        - All security findings must be classified by severity
        - Sensitive security details must follow disclosure policies
        - Compliance mapping must reference specific control IDs
        - Documents must pass security review before publication
      expected_output:
        - Threat model documents with identified attack vectors
        - Security architecture review reports
        - Compliance mapping matrices (requirements to controls)
        - Security runbooks for incident response
      archetype: The Sentinel
      responsibilities:
        - Produce threat model documentation
        - Map compliance requirements to implemented controls
        - Review all documentation for security implications
        - Maintain security documentation standards
      role_skills:
        - Threat modeling and risk assessment
        - Security architecture documentation
        - Compliance framework mapping (SOC2, ISO 27001, NIST)
        - Security review and sensitive data handling
        - Incident response documentation
      role_collaborators:
        - Receives architecture blueprints from Blueprint Crafter (BC)
        - Provides security context to Runbook Crafter (RB)
        - Reports compliance findings to Governance Compliance Auditor (GCA)
        - Supplies security guidelines to User Guide Crafter (UG)
      role_adoption_checklist:
        - Threat model covers all identified attack surfaces
        - Compliance mapping references specific control IDs
        - Security review checklist applied to all documents
        - Sensitive information handling policy followed
        - Incident response runbooks tested and current
    doc_context:
      primary_action: "security documentation"
      primary_output: "threat models and compliance mapping"
      cli_command: "scaffold-sds"
      example_scenario: "Produce a threat model and SOC2 compliance mapping for a new payment processing API"
      constitution:
        hard_stop:
          - "Never publish security documentation without security review"
          - "Never disclose sensitive vulnerability details outside approved channels"
          - "Never bypass compliance control mapping requirements"
        mandatory:
          - "All security findings must be classified by severity"
          - "Compliance mapping must reference specific control IDs"
          - "Sensitive security details must follow disclosure policies"
          - "Security review must be completed before publication"
        preferred:
          - "Use structured threat analysis formats (STRIDE, DREAD)"
          - "Include risk ratings with each identified threat"
          - "Provide remediation recommendations alongside findings"
    deliverables:
      - name: Threat Models
        description: Attack vector identification with severity classification
      - name: Compliance Mapping
        description: Requirements-to-controls matrix with control IDs
      - name: Security Reviews
        description: Documentation security assessment reports
    collaboration:
      - target: BC
        interaction: Receives architecture blueprints for security analysis
        direction: upstream
      - target: RB
        interaction: Provides security context for operational runbooks
        direction: downstream
      - target: GCA
        interaction: Reports compliance findings for audit
        direction: downstream
      - target: UG
        interaction: Supplies security guidelines for user documentation
        direction: downstream

YAML Structure Checklist

Verify your custom persona YAML includes all required fields:

  • id -- Unique short identifier (2-5 uppercase characters)
  • name -- Full descriptive name
  • fcc_phase -- One of: Find, Create, Critique, All, Orchestration
  • role_title -- Professional title
  • color -- Hex color code for visual representation
  • riscear -- All 10 R.I.S.C.E.A.R. components
  • doc_context -- Documentation generation context with constitution
  • deliverables -- Named artifacts with descriptions
  • collaboration -- Directed relationships with other personas

Optional fields:

  • category -- One of: core, integration, governance, stakeholder, champion
  • champion_of -- Base persona ID (only for champion personas)
  • orchestrates -- List of persona IDs (only for champion personas)

Step 2: Register in PersonaRegistry

Load your custom persona alongside the built-in ones:

from fcc.personas.registry import PersonaRegistry

# Option 1: Load from a single file
custom_registry = PersonaRegistry.from_yaml("my_project/custom_personas.yaml")

# Option 2: Merge with built-in personas
built_in = PersonaRegistry.from_yaml_directory("data/personas/")
combined = built_in.merge(custom_registry)

print(f"Total personas: {len(combined)}")
print(f"Custom persona: {combined.get('SDS').name}")

You can also use from_yaml_files() to load multiple files:

registry = PersonaRegistry.from_yaml_files(
    "data/personas/core_personas.yaml",
    "data/personas/integration_specialists.yaml",
    "my_project/custom_personas.yaml",
)

Step 3: Validate Against Schema

Validate your custom persona YAML against the JSON schema:

registry = PersonaRegistry.from_yaml_validated(
    yaml_path="my_project/custom_personas.yaml",
    schema_path="data/schemas/persona.schema.json",
)
print("Validation passed!")

If validation fails, you will get a jsonschema.ValidationError with details about which field is missing or incorrectly formatted.

Step 4: Add to a Workflow Graph

Create a workflow graph that includes your custom persona. You can either:

Option A: Create a New Workflow JSON

{
  "meta": {
    "id": "custom_workflow",
    "title": "Custom Workflow with Security Specialist",
    "description": "Base workflow extended with SDS persona."
  },
  "nodes": [
    {"id": "RC", "name": "Research Crafter", "type": "persona"},
    {"id": "BC", "name": "Blueprint Crafter", "type": "persona"},
    {"id": "DE", "name": "Documentation Evangelist", "type": "persona"},
    {"id": "RB", "name": "Runbook Crafter", "type": "persona"},
    {"id": "UG", "name": "User Guide Crafter", "type": "persona"},
    {"id": "SDS", "name": "Security Documentation Specialist", "type": "persona"}
  ],
  "edges": [
    {"from": "RC", "to": "BC", "label": "research_inventory", "type": "handoff"},
    {"from": "BC", "to": "DE", "label": "blueprints_specs", "type": "handoff"},
    {"from": "BC", "to": "SDS", "label": "architecture_for_security", "type": "handoff"},
    {"from": "SDS", "to": "RB", "label": "security_context", "type": "handoff"},
    {"from": "SDS", "to": "UG", "label": "security_guidelines", "type": "handoff"},
    {"from": "DE", "to": "RB", "label": "publish_handoff", "type": "handoff"},
    {"from": "DE", "to": "UG", "label": "publish_handoff", "type": "handoff"},
    {"from": "DE", "to": "BC", "label": "standards_edits", "type": "feedback"}
  ]
}

Option B: Build Programmatically

from fcc.workflow.models import WorkflowMeta, WorkflowNode, WorkflowEdge
from fcc.workflow.graph import WorkflowGraph

meta = WorkflowMeta(
    id="custom_workflow",
    title="Custom Workflow with Security Specialist",
    description="Base workflow extended with SDS persona.",
)

nodes = [
    WorkflowNode(id="RC", name="Research Crafter", type="persona"),
    WorkflowNode(id="BC", name="Blueprint Crafter", type="persona"),
    WorkflowNode(id="DE", name="Documentation Evangelist", type="persona"),
    WorkflowNode(id="RB", name="Runbook Crafter", type="persona"),
    WorkflowNode(id="UG", name="User Guide Crafter", type="persona"),
    WorkflowNode(id="SDS", name="Security Documentation Specialist", type="persona"),
]

edges = [
    WorkflowEdge(from_id="RC", to_id="BC", label="research_inventory", type="handoff"),
    WorkflowEdge(from_id="BC", to_id="DE", label="blueprints_specs", type="handoff"),
    WorkflowEdge(from_id="BC", to_id="SDS", label="architecture_for_security", type="handoff"),
    WorkflowEdge(from_id="SDS", to_id="RB", label="security_context", type="handoff"),
    WorkflowEdge(from_id="SDS", to_id="UG", label="security_guidelines", type="handoff"),
    WorkflowEdge(from_id="DE", to_id="RB", label="publish_handoff", type="handoff"),
    WorkflowEdge(from_id="DE", to_id="UG", label="publish_handoff", type="handoff"),
    WorkflowEdge(from_id="DE", to_id="BC", label="standards_edits", type="feedback"),
]

graph = WorkflowGraph(meta=meta, nodes=nodes, edges=edges)

# Save for later use
graph.to_json("my_project/custom_workflow.json")

Step 5: Run a Simulation

from fcc.simulation.engine import SimulationEngine

engine = SimulationEngine(graph=graph, max_steps=50)
history = engine.run(start_node="RC", initial_payload="Document payment API security")

for event in history.events[:6]:
    print(f"Step {event['step']}: {event['actor']} (via {event['edge_label']})")

Step 6: Generate Documentation

Use the DocGenerator to produce docs-as-code for your custom persona:

from pathlib import Path
from fcc.scaffold.doc_generator import DocGenerator

generator = DocGenerator(registry=combined)
count = generator.generate_persona_docs("SDS", Path("output/docs"))
print(f"Generated {count} documentation files for SDS")

This produces the full documentation suite for your custom persona using the Jinja2 templates, including specification pages, tutorials, prompts, workflows, and coordination documentation.

Best Practices

  1. Use unique IDs: Avoid conflicts with built-in persona 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)
  2. Complete the R.I.S.C.E.A.R.: All 10 components should be populated -- they drive documentation generation and simulation prompts
  3. Define collaboration explicitly: Specify upstream, downstream, and peer relationships to enable cross-reference generation
  4. Include constitution rules: hard_stop, mandatory, and preferred rules constrain persona behavior
  5. Validate before use: Always validate against the schema before integrating into workflows

Next Steps