Skip to content

Persona Interactions

This tutorial explains how FCC personas interact through the cross-reference matrix, how to read and query interaction data, and how to extend the matrix for custom personas.

Why Persona Interactions Matter

The FCC cycle -- Find, Create, Critique -- is not a simple linear pipeline. Each phase involves multiple personas exchanging deliverables, providing feedback, coordinating standards, and reporting governance status. These interactions determine:

  • Workflow correctness: Does the right artifact reach the right persona at the right time?
  • Quality assurance: Are feedback loops in place to catch errors before handoff?
  • Governance compliance: Are oversight relationships defined and enforced?
  • Scalability: Can new personas be added without breaking existing flows?

The cross-reference matrix encodes all of these interactions as structured, queryable data.

The 5 Relationship Types

handoff: Work Transfer

A handoff moves a deliverable from producer to consumer. The source persona has completed its contribution; the target persona takes ownership.

RC --[handoff]--> BC
"Delivers research inventory; clarifies context"

RC produces the research inventory. BC receives it and uses it to create blueprints. RC's work on that artifact is done.

feedback: Evaluation Return

Feedback flows in the reverse direction -- from a reviewer back to a producer. No ownership changes; the producer uses the feedback to improve.

DE --[feedback]--> BC
"Returns standards and edits on blueprints"

DE reviews BC's blueprints and sends back corrections. BC still owns the blueprint and incorporates the feedback.

coordination: Bidirectional Alignment

Coordination connects two personas that must stay synchronized. Neither owns the other's deliverable, but both benefit from shared context.

RB <--[coordination]--> UG
"Cross-links quick fixes and operational steps"

RB and UG each maintain their own docs, but coordinate to ensure operational steps and user guides reference each other correctly.

governance: Oversight Reporting

Governance relationships carry authority. The source persona reports compliance status to an oversight persona (typically GCA). Unlike feedback, governance can block downstream progress.

DGS --[governance]--> GCA
"Reports compliance status for governance audit"

DGS must demonstrate data governance compliance to GCA before artifacts can proceed.

champion-of: Orchestration Elevation

Champion-of links a champion persona to its base persona. The champion coordinates a team that includes the base persona, elevating individual contributions into a unified package.

RCHM --[champion-of]--> RC
"Champions and elevates the Research Crafter persona"

RCHM does not replace RC -- it orchestrates RC alongside CIA, STE, and RIC to produce a unified research package.

Reading the Cross-Reference Matrix

Loading the Matrix

from fcc.personas.cross_reference import CrossReferenceMatrix

matrix = CrossReferenceMatrix.from_yaml("data/personas/cross_reference.yaml")
print(f"Total entries: {len(matrix)}")
print(f"Personas covered: {len(matrix.all_persona_ids())}")

Output:

Total entries: 106
Personas covered: 24

Upstream: Who Sends Work to This Persona?

# What inputs does BC receive?
for entry in matrix.upstream("BC"):
    print(f"  {entry.source_id} -> BC [{entry.relationship_type}]: {entry.interaction}")

Output:

  RC -> BC [handoff]: Delivers research inventory; clarifies context
  CIA -> BC [handoff]: Supplies catalog data for blueprint context
  DGS -> BC [handoff]: Provides governance context for blueprint creation
  RIC -> BC [handoff]: Provides structured data for blueprint creation
  DE -> BC [feedback]: Returns standards and edits on blueprints
  RB -> BC [feedback]: Provides operational feedback on specs
  UG -> BC [feedback]: Provides usability feedback on specs
  BV -> BC [feedback]: Returns quality validation results on blueprints
  UMC -> BC [feedback]: Returns visual prototypes aligned to specifications
  AMS -> BC [feedback]: Provides quality feedback on blueprint accuracy

Downstream: Where Does This Persona Send Output?

# Where does RC send its deliverables?
for entry in matrix.downstream("RC"):
    print(f"  RC -> {entry.target_id} [{entry.relationship_type}]: {entry.interaction}")

Output:

  RC -> BC [handoff]: Delivers research inventory; clarifies context
  RC -> DE [handoff]: Provides annotated references for cross-linking
  RC -> RB [handoff]: Flags operational scenarios for automation
  RC -> UG [handoff]: Compiles user pain points for onboarding guides
  RC -> TS [handoff]: Provides requirements for traceability linking

Peers: Who Coordinates with This Persona?

# Who does UG coordinate with?
for entry in matrix.peers("UG"):
    other = entry.target_id if entry.source_id == "UG" else entry.source_id
    print(f"  UG <-> {other}: {entry.interaction}")

Output:

  UG <-> RB: Cross-links quick fixes and operational steps
  UG <-> RB: Cross-links quick fixes and recovery steps

Walk-Through: Tracing a Complete Workflow

Let us trace a complete path through the 24-persona system, from research champion to published content.

RCHM -> RC -> BC -> DE -> UGCH -> UG -> SCP

graph LR
    RCHM[RCHM] -->|champion-of| RC[RC]
    RCHM -->|handoff| RC
    RC -->|handoff| BC
    BC -->|handoff| DE
    DE -->|handoff| UGCH[UGCH]
    UGCH -->|champion-of| UG[UG]
    UGCH -->|handoff| UG
    UG -->|handoff| SCP[SCP]

    style RCHM fill:#FFF8E1,stroke:#F9A825
    style RC fill:#E3F2FD,stroke:#1565C0
    style BC fill:#E8F5E9,stroke:#2E7D32
    style DE fill:#FFF3E0,stroke:#EF6C00
    style UGCH fill:#FFF8E1,stroke:#F9A825
    style UG fill:#E8F5E9,stroke:#2E7D32
    style SCP fill:#F3E5F5,stroke:#6A1B9A

Step 1 -- RCHM orchestrates RC. RCHM is the Research Crafter Champion. It coordinates RC, CIA, STE, and RIC into a unified research package.

Step 2 -- RC hands off to BC. RC delivers the research inventory to BC, providing the knowledge base that blueprints will be built on.

Step 3 -- BC hands off to DE. BC submits completed blueprints to DE for documentation review and standards compliance.

Step 4 -- DE hands off to UGCH. DE approves the documentation and hands off to UGCH for user-facing publishing orchestration.

Step 5 -- UGCH orchestrates UG. UGCH coordinates UG, SCP, and EC to produce a multi-channel publishing package.

Step 6 -- UG hands off to SCP. UG provides completed user guides to SCP for multi-channel distribution.

Tracing Programmatically

def trace_path(matrix, path):
    """Trace a sequence of persona IDs through the matrix."""
    for i in range(len(path) - 1):
        entries = matrix.between(path[i], path[i + 1])
        for entry in entries:
            print(f"  {entry.source_id} -> {entry.target_id} "
                  f"[{entry.relationship_type}, {entry.strength}]: "
                  f"{entry.interaction}")
        if not entries:
            print(f"  {path[i]} -> {path[i+1]}: NO ENTRY FOUND")

trace_path(matrix, ["RCHM", "RC", "BC", "DE", "UGCH", "UG", "SCP"])

Output:

  RCHM -> RC [champion-of, primary]: Champions and elevates the Research Crafter persona
  RCHM -> RC [handoff, primary]: Orchestrates core research activities
  RC -> BC [handoff, primary]: Delivers research inventory; clarifies context
  BC -> DE [handoff, primary]: Submits blueprints for review
  DE -> UGCH [handoff, primary]: Hands off approved content for publishing orchestration
  UGCH -> UG [champion-of, primary]: Champions and elevates the User Guide Crafter persona
  UGCH -> UG [handoff, primary]: Orchestrates user guide creation
  UG -> SCP [handoff, primary]: Provides user guides for multi-channel publishing

Querying Interactions Programmatically

Find All Personas in a Relationship Type

# All governance relationships
gov_entries = matrix.by_type("governance")
print(f"Governance entries: {len(gov_entries)}")
for entry in gov_entries:
    print(f"  {entry.source_id} -> {entry.target_id}: {entry.interaction}")

Output:

Governance entries: 4
  DGS -> GCA: Reports compliance status for governance audit
  PTE -> GCA: Reports privacy compliance for governance audit
  AMS -> GCA: Reports validation results for governance compliance

Find All Interactions Between Two Personas

# Everything between BCHM and BC
for entry in matrix.between("BCHM", "BC"):
    print(f"  [{entry.relationship_type}] {entry.interaction} ({entry.strength})")

Output:

  [champion-of] Champions and elevates the Blueprint Crafter persona (primary)
  [handoff] Orchestrates core blueprint creation (primary)

Build an Adjacency Summary

# For each persona, count upstream and downstream links
for pid in sorted(matrix.all_persona_ids()):
    up = len(matrix.upstream(pid))
    down = len(matrix.downstream(pid))
    print(f"  {pid:5s}: {up} upstream, {down} downstream")

Adding New Cross-Reference Entries

For Custom Personas

When you add a custom persona, you need to add cross-reference entries to connect it to the existing matrix.

from fcc.personas.cross_reference import CrossReferenceEntry, CrossReferenceMatrix

# Load the existing matrix
matrix = CrossReferenceMatrix.from_yaml("data/personas/cross_reference.yaml")

# Create entries for a new persona "APT" (API Tester)
new_entries = [
    CrossReferenceEntry(
        source_id="BC",
        target_id="APT",
        relationship_type="handoff",
        interaction="Provides API specifications for test generation",
        strength="primary",
    ),
    CrossReferenceEntry(
        source_id="APT",
        target_id="BV",
        relationship_type="handoff",
        interaction="Submits test results for quality validation",
        strength="primary",
    ),
    CrossReferenceEntry(
        source_id="APT",
        target_id="BC",
        relationship_type="feedback",
        interaction="Reports API inconsistencies for specification correction",
        strength="primary",
    ),
]

for entry in new_entries:
    matrix.add(entry)

# Save the updated matrix
matrix.to_yaml("data/personas/cross_reference.yaml")
print(f"Matrix now has {len(matrix)} entries")

Merging Auto-Generated and Hand-Authored

from fcc.personas.registry import PersonaRegistry
from fcc.personas.cross_reference import CrossReferenceMatrix

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

yaml_matrix = CrossReferenceMatrix.from_yaml("data/personas/cross_reference.yaml")
auto_matrix = CrossReferenceMatrix.from_personas(registry)

# YAML entries take precedence (better descriptions, curated strengths)
combined = yaml_matrix.merge_with_precedence(auto_matrix)
print(f"YAML: {len(yaml_matrix)}, Auto: {len(auto_matrix)}, Combined: {len(combined)}")

How the Matrix Flows into Generated Documentation

The docs-as-code pipeline uses cross-reference data to generate per-persona coordination pages. When you run fcc generate-docs, each persona's documentation includes:

  • Upstream interactions: Who provides input to this persona
  • Downstream interactions: Where this persona sends its output
  • Peer coordination: Who this persona coordinates with
  • Champion relationships: Which champion orchestrates this persona (if any)

This means changes to cross_reference.yaml automatically propagate to all generated documentation on the next build.

Next Steps