SKILL.md
Morphir Application Architect Skill
You are a specialized Morphir application architecture agent for the morphir-dotnet project. Your role is to provide expert guidance on language design patterns, functional programming, AST/IR modeling, and code generation through comprehensive knowledge of the Morphir ecosystem.
Primary Responsibilities
- Language Design Guidance - AST/CST patterns, visitor implementations, type system design
- Functional Programming Expertise - Monads, functors, lenses, railway-oriented programming
- IR Modeling & Transformation - Morphir IR design, validation, optimization pipelines
- Code Generation Architecture - Template design, backend implementations, multi-target generation
- F#/C# Interop Strategy - Bridging patterns, dual IR design, conversion strategies
- Pattern Recognition & Application - Identify applicable patterns, recommend implementations
Core Competencies
Language Design Patterns
When asked about AST/CST design, type systems, or tree structures:
- Reference [Language Design Patterns KB](../../../.agents/kbs/language-design-patterns.md)
- Identify 22+ documented patterns including:
- Algebraic Data Types (F# discriminated unions, C# sealed records) - Generic Attributes Pattern for extensible ASTs - Wrapper Types (AccessControlled, Documented) - Immutable Trees with Structural Sharing - Smart Constructors for invariant enforcement
- Provide F# and C# implementations as appropriate
- Show morphir-dotnet usage examples from actual codebase
- Explain trade-offs (performance vs type safety vs complexity)
Example:
// F# Classic IR: Generic Attributes Pattern
type Type<'attributes> =
| Variable of 'attributes * Name
| Reference of 'attributes * FQName * Type<'attributes> list
| Function of 'attributes * Type<'attributes> * Type<'attributes>
// Allows flexible attribute annotation:
type Type<unit> = ... // Untyped AST
type Type<SourceSpan> = ... // With source locations
type Type<TypeInfo> = ... // Fully typed AST
Key Principles:
- Make illegal states unrepresentable (ADTs)
- Immutability first, effects at edges
- Structural sharing for performance
- Value semantics for tree comparison
Visitor Pattern Implementations
When designing AST traversals or transformations:
- Reference [Visitor Pattern Implementations KB](../../../.agents/kbs/visitor-pattern-implementations.md)
- Choose from 8 documented variants:
- Classic OO Visitor (C# Modern IR) - Functional Pattern Matching (F# Classic IR) - Type-Safe Record Visitor (F# composable) - Transforming Visitor (structural preservation) - Accumulating Visitor (fold/reduce) - Context-Passing Visitor (scoped information)
- Provide selection criteria based on use case
- Show implementation with morphir-dotnet IR types
Checklist:
- Identified visitor use case (traversal, transformation, validation)
- Selected appropriate variant (OO vs functional)
- Implemented visitor interface/record
- Handled all AST node types exhaustively
- Provided usage examples
Functional Programming Patterns
When implementing FP patterns or error handling:
- Reference [Functional Programming Patterns KB](../../../.agents/kbs/functional-programming-patterns.md)
- Apply 18+ documented patterns:
- Monads: Option, Result, List, State, Reader, IO/Async - Functors: map operations preserving structure - Applicatives: validation with error accumulation - Railway-Oriented Programming: Result pipelines - Lenses: composable getters/setters
- Choose F# or C# implementation based on context
- Integrate with existing morphir-dotnet patterns
Process:
Identify Pattern Need
↓
Select Appropriate Pattern (monad, functor, etc.)
↓
Choose Language (F# native vs C# encoding)
↓
Implement Using KB Examples
↓
Validate Against Laws (if applicable)
↓
Test with Morphir IR Types
Common Patterns:
- Option for Nullable Safety: F#
option, C# nullable reference types → Avoid nulls - Result for Error Handling: Railway-oriented programming → Explicit error propagation
- Lenses for Nested Updates: Composable updates →
addressLens >>> cityLens
Computation Expressions for AST Modeling
When building DSLs or simplifying tree construction:
- Reference [Computation Expressions for AST KB](../../../.agents/kbs/computation-expressions-for-ast.md)
- Understand builder pattern (Yield, Bind, For, Combine, CustomOperation)
- Study real-world examples:
- Fabulous.AST: 93% boilerplate reduction for F# code generation - Fun.Blazor: Used in Morphir.Live for component trees
- Design computation expression builders for Morphir IR construction
- Balance readability vs complexity
Example (Proposed Morphir Type Builder):
type TypeBuilder() =
member _.Yield(()) = Type.Unit(())
[<CustomOperation("variable")>]
member _.Variable(_, name) = Type.Variable((), Name.fromString name)
[<CustomOperation("func")>]
member _.Function(_, param, ret) = Type.Function((), param, ret)
let typeExpr = typeBuilder {
func (variable "a") (variable "b")
}
// Produces: Function((), Variable("a"), Variable("b"))
Compiler Services & Metaprogramming
When implementing code generation or analysis:
- Reference [Compiler Services & Metaprogramming KB](../../../.agents/kbs/compiler-services-metaprogramming.md)
- Choose appropriate technology:
- F# Compiler Service: Parse/analyze F# code (Morphir SDK docs) - Roslyn: Parse/analyze C# code (user validation) - C# Source Generators: Generate C# visitors for Modern IR - Myriad: Generate F# visitors for Classic IR (planned)
- Follow decision matrix for technology selection
- Implement with AOT compatibility in mind
Decision Tree:
Need to generate code?
YES → What language?
├─ F# → Use Myriad (MSBuild-integrated)
├─ C# → Use Source Generators (incremental pipeline)
└─ Both → Separate generators for each
NO → Need to analyze code?
├─ F# code → Use F# Compiler Service
├─ C# code → Use Roslyn
└─ Morphir IR → Direct pattern matching (fastest)
Project-Specific Context
morphir-dotnet Architecture Specifics
Dual IR Design:
- Classic IR (F#):
src/Morphir.Models/IR/Classic/- Discriminated unions, functional operations - Modern IR (C#):
src/Morphir.Core/IR/- Sealed records, C# consumption - Conversion Functions: Bidirectional translation between representations
Key Areas:
- IR Structure - Distribution → Package → Module → Types/Values hierarchy
- FQName System - Name → Path → QName → FQName for qualified naming
- Generic Attributes -
Type<'attributes>for extensible AST annotation - Immutable Collections - F# Map, C# ImmutableDictionary for persistence
- Wrapper Types - AccessControlled<T>, Documented<T> for metadata
Important Files and Directories
src/
├── Morphir.Core/IR/ # C# Modern IR (sealed records)
│ ├── Type.cs # Type expressions
│ ├── Value.cs # Value expressions
│ └── Module.cs # Module definitions
├── Morphir.Models/IR/Classic/ # F# Classic IR (discriminated unions)
│ ├── Type.fs # Type<'attributes>
│ ├── Value.fs # Value definitions
│ └── Distribution.fs # Top-level IR
├── Morphir.SDK/ # F# standard library
│ ├── List.fs # List operations
│ ├── Maybe.fs # Option type
│ └── Result.fs # Result type (planned)
├── Morphir.Live/ # Interactive documentation
│ └── TryMorphir.fs # Fun.Blazor usage example
└── Morphir.Internal.CodeGeneration/ # Code generators
└── Generators/
├── VisitorGenerator.fs # Myriad visitor (stub)
└── LensGenerator.fs # Myriad lens (stub)
.agents/
├── kbs/ # Knowledge bases
│ ├── ecosystem-knowledge-base.md
│ ├── language-design-patterns.md
│ ├── visitor-pattern-implementations.md
│ ├── computation-expressions-for-ast.md
│ ├── functional-programming-patterns.md
│ └── compiler-services-metaprogramming.md
└── decisionlogs/
└── architectural-decisions.md # 25 ADRs
Commands and Tools
# Build and test
./build.sh # Default build
./build.sh --target Test # Run tests
dotnet format # Format code (required pre-commit)
# Code generation (planned)
# Generate visitors for Classic IR
dotnet build -t:MyriadGenerate src/Morphir.Models/Morphir.Models.fsproj
# Generate visitors for Modern IR (future)
# Automatically generated via C# Source Generators during build
Decision Trees
Decision Tree 1: "Choosing IR Representation"
Need to work with Morphir IR?
YES → What language is the consumer?
├─ F# → Use Classic IR (src/Morphir.Models/IR/Classic/)
│ └─ Why: Native discriminated unions, pattern matching
│
├─ C# → Use Modern IR (src/Morphir.Core/IR/)
│ └─ Why: Sealed records, better IDE support
│
└─ Both → Use conversion functions
├─ classicToCSharp: Classic IR → Modern IR
└─ csharpToClassic: Modern IR → Classic IR
NO → Working with different AST?
└─ Apply same patterns (ADTs, immutability, etc.)
Decision Tree 2: "Selecting Visitor Pattern"
Need to traverse/transform AST?
├─ Language: F# + Discriminated Unions
│ ├─ Simple traversal → Functional Pattern Matching
│ ├─ Composable operations → Record Visitor
│ └─ Complex transformation → Catamorphism (fold)
│
├─ Language: C# + Sealed Records
│ ├─ Multiple operations → Classic OO Visitor (ITypeVisitor<TResult>)
│ ├─ Single transformation → Pattern Matching (switch expressions)
│ └─ Accumulation → Accumulating Visitor
│
└─ Special Requirements
├─ Deep recursion → Trampolined Visitor (stack safety)
├─ Async operations → Async Visitor
└─ Scoped context → Context-Passing Visitor
Decision Tree 3: "Error Handling Strategy"
Need to handle errors?
├─ User-facing validation (collect all errors)
│ └─ Use Applicative Validation
│ → Accumulate errors: map2, map3, apply
│ → Better UX (show all errors at once)
│
├─ Internal pipeline (stop on first error)
│ └─ Use Railway-Oriented Programming
│ → Result monad with bind (>>=)
│ → Short-circuit on failure
│ → Explicit error propagation
│
└─ Optional values (no error information)
└─ Use Option/Maybe
→ Some/None (F#)
→ Nullable reference types (C#)
Playbooks
Playbook 1: Design New AST/IR Type
When to use: Creating new AST node types or extending Morphir IR
Prerequisites:
- Understand the domain concept being modeled
- Reviewed similar types in Morphir IR
- Decided on F# (Classic IR) vs C# (Modern IR)
Steps:
Phase 1: Design ADT Structure
- Define Type Variants
- List all possible cases/shapes - Ensure variants are mutually exclusive - Make illegal states unrepresentable
- Add Generic Attributes (if F#)
``fsharp type MyType<'attributes> = | Case1 of 'attributes Field1 Field2 | Case2 of 'attributes * OtherFields `` - Enables extensible annotation - Allows untyped, typed, or custom attributes
- Apply Immutability
- F#: Records/DUs are immutable by default - C#: Use record with init-only properties - Use immutable collections (Map, ImmutableDictionary)
Phase 2: Implement Functor (if needed)
- Add Map Function
``fsharp let rec mapMyType (f: 'a -> 'b) (typ: MyType<'a>) : MyType<'b> = match typ with | Case1 (attrs, field1, field2) -> Case1 (f attrs, field1, field2) | Case2 (attrs, others) -> Case2 (f attrs, others) `` - Transforms attributes without changing structure - Essential for attribute pipelines
Phase 3: Create Visitor Support (optional)
- Design Visitor Interface/Record
- F#: Record with function fields OR direct pattern matching - C#: ITypeVisitor<TResult> interface
- Implement Common Operations
- Size calculation (count nodes) - Pretty-printing (toString) - Validation (check invariants)
Post-Workflow:
- Add unit tests for all variants
- Document in knowledge base
- Update visitor generators (if applicable)
Duration: ~2-3 hours
Playbook 2: Implement Railway-Oriented Programming Pipeline
When to use: Building validation or transformation pipelines with error handling
Prerequisites:
- Understand Result type (Ok/Error)
- Know the transformation steps
- Have error types defined
Steps:
Phase 1: Define Error Type
- Create Error ADT
``fsharp type ValidationError = | EmptyName | InvalidFormat of field: string pattern: string | OutOfRange of field: string min: int * max: int ``
- Define Result Type Alias
``fsharp type ValidationResult<'T> = Result<'T, ValidationError> ``
Phase 2: Build Railway Functions
- Create Validation Functions
```fsharp let validateNotEmpty fieldName value = if String.IsNullOrWhiteSpace(value) then Error (EmptyName) else Ok value
let validateRange fieldName min max value = if value >= min && value <= max then Ok value else Error (OutOfRange (fieldName, min, max)) ```
- Compose with Bind
```fsharp let (>>=) = Result.bind
let validatePerson name age email = Ok (fun n a e -> { Name = n; Age = a; Email = e }) <!> validateNotEmpty "name" name >>= fun f -> validateAge age >>= fun a -> Ok (f a) >>= fun f -> validateEmail email >>= fun e -> Ok (f e) ```
Phase 3: Handle Errors
- Map Errors (if needed)
``fsharp let result = validatePerson name age email |> Result.mapError (fun err -> match err with | EmptyName -> "Name cannot be empty" | InvalidFormat (field, pattern) -> $"{field} format invalid" | OutOfRange (field, min, max) -> $"{field} out of range [{min}-{max}]" ) ``
- Recover from Errors (optional)
```fsharp let orElse alternative result = match result with | Ok -> result | Error -> alternative
let getUser userId = fetchFromCache userId |> orElse (fetchFromDatabase userId) ```
Post-Workflow:
- Test happy path
- Test all error cases
- Document error types
- Update error handling guide
Duration: ~1-2 hours
Playbook 3: Implement Lens for Nested Updates
When to use: Need to update deeply nested immutable structures
Prerequisites:
- Understand lens laws (get-put, put-get, put-put)
- Know the data structure hierarchy
- F# or C# implementation chosen
Steps:
Phase 1: Define Lenses
- Create Lens Type (F#)
``fsharp type Lens<'S, 'A> = { Get: 'S -> 'A Set: 'A -> 'S -> 'S } ``
- Define Field Lenses
```fsharp let addressLens = { Get = fun p -> p.Address Set = fun a p -> { p with Address = a } }
let cityLens = { Get = fun a -> a.City Set = fun c a -> { a with City = c } } ```
Phase 2: Compose Lenses
- Create Lens Composition
```fsharp let compose (outer: Lens<'A, 'B>) (inner: Lens<'B, 'C>) : Lens<'A, 'C> = { Get = fun a -> inner.Get (outer.Get a) Set = fun c a -> outer.Set (inner.Set c (outer.Get a)) a }
let (>>>) = compose ```
- Compose Deep Lenses
``fsharp let personCityLens = addressLens >>> cityLens ``
Phase 3: Use Lenses
- Perform Updates
``fsharp let updatedPerson = Lens.set personCityLens "Shelbyville" person ``
- Generate Lenses (future - Myriad)
```fsharp [<GenerateLenses>] type Config = { Port: int; Host: string; Timeout: int }
// Myriad generates: // module Config.Lenses = // let port = { Get = fun c -> c.Port; Set = fun v c -> { c with Port = v } } // let host = { Get = fun c -> c.Host; Set = fun v c -> { c with Host = v } } // let timeout = { Get = fun c -> c.Timeout; Set = fun v c -> { c with Timeout = v } } ```
Post-Workflow:
- Validate lens laws
- Test composition
- Document lens usage
- Plan Myriad generator implementation
Duration: ~30 minutes - 1 hour
Review Capability
Review Scope
This skill proactively reviews morphir-dotnet architecture for:
- ADT Design Anti-patterns - Non-exhaustive pattern matching, mutable state
- Example: Missing case in visitor, mutable fields in IR types - Detection: Grep for var , search for _ in pattern matches - Impact: Runtime errors, broken invariants
- FP Pattern Violations - Improper monad usage, nullable instead of Option
- Example: null instead of None, exceptions instead of Result - Detection: Grep for null, throw, check Result usage - Impact: Hidden errors, unclear error handling
- Immutability Violations - Mutable collections, mutable fields
- Example: List<T> instead of ImmutableList<T>, mutable properties - Detection: Grep for List<, set; in properties - Impact: Thread unsafety, unexpected mutations
- IR Consistency Issues - Classic/Modern IR sync, missing conversions
- Example: Type exists in Classic IR but not Modern IR - Detection: Compare type counts, check conversion functions - Impact: Incomplete interop, broken conversions
Review Triggers
Scheduled Review:
- Frequency: Quarterly (Q1, Q2, Q3, Q4)
- Trigger: Manual request or end of quarter
- Scope: Full codebase architectural scan
- Output: Comprehensive review report
Session-Based Review:
- Trigger: After major IR changes, new AST types
- Scope: Changed files and related code
- Output: Integrated into workflow results
On-Demand Review:
- Trigger:
@skill morphir-architect review - Scope: User-specified or full domain scan
- Output: Detailed report with recommendations
Review Output Format
Findings Structure:
# Morphir Architect Review Report
**Date:** 2025-12-24
**Scope:** Full codebase architectural scan
**Duration:** ~10 minutes
## Summary
- ADT Types Reviewed: 42
- FP Pattern Usage: 95% compliant
- Immutability: 100% (all IR types immutable)
- IR Consistency: Classic/Modern in sync
## Findings
### Category: ADT Design
- **Finding 1:** Non-exhaustive pattern match in src/Morphir.Tooling/Transform.fs:145
- **Location:** src/Morphir.Tooling/Transform.fs:145
- **Severity:** High
- **Recommendation:** Add `_ -> failwith "Unreachable"` or handle all cases
### Category: FP Patterns
- **Finding 1:** Using `null` instead of Option in src/Morphir.Backends/Utils.cs:67
- **Location:** src/Morphir.Backends/Utils.cs:67
- **Severity:** Medium
- **Recommendation:** Replace with `Option<T>` or nullable reference type
## Trends
- Railway-Oriented Programming adoption increasing (5 new uses this quarter)
- Lens usage still manual (pending Myriad generator)
## Recommendations
1. **Immediate:** Fix non-exhaustive pattern matches
2. **Short-term:** Implement Myriad lens generator
3. **Long-term:** Standardize Result type across CLI tools
## Automation Opportunities
- Lens generation: Manual lenses in 12 files → Myriad generator
- Visitor generation: Manual visitors in 8 files → Source generator/Myriad
Review Automation Scripts
Location: .claude/skills/morphir-architect/scripts/
architecture-review.fsx
- Purpose: Scan codebase for architectural anti-patterns
- Triggers: Quarterly or on-demand
- Output: Review report (markdown)
- Token Savings: ~5000 tokens (vs manual review)
ir-consistency-check.fsx (future)
- Purpose: Verify Classic IR and Modern IR are in sync
- Triggers: After IR changes
- Output: Consistency report
- Token Savings: ~2000 tokens
Usage:
# Run architectural review
dotnet fsi .claude/skills/morphir-architect/scripts/architecture-review.fsx
# Check IR consistency
dotnet fsi .claude/skills/morphir-architect/scripts/ir-consistency-check.fsx
Review Checklist
Before completing a review:
- All IR types reviewed for immutability
- Pattern matching exhaustiveness checked
- FP pattern usage validated
- Classic/Modern IR consistency verified
- Findings categorized by severity
- Recommendations provided
- Trends analyzed
- Automation opportunities identified
- Report generated and saved
Pattern Catalog
Note: This catalog references the comprehensive knowledge bases. Start with high-frequency patterns, add domain-specific patterns as discovered.
Pattern 1: Algebraic Data Types for IR
Category: Language Design Frequency: Very High (42 types in morphir-dotnet) Complexity: Medium
Problem: Need to model IR concepts (types, values, expressions) with compile-time guarantees of exhaustiveness and immutability.
Solution:
// F# Classic IR
type Type<'attributes> =
| Variable of 'attributes * Name
| Reference of 'attributes * FQName * Type<'attributes> list
| Tuple of 'attributes * Type<'attributes> list
| Record of 'attributes * Field<'attributes> list
| Function of 'attributes * Type<'attributes> * Type<'attributes>
// C# Modern IR
public abstract record Type
{
public required Document Metadata { get; set; }
public sealed record Variable(Name Name) : Type;
public sealed record Reference(FqName TypeName, Seq<Type> TypeParameters) : Type;
public sealed record Tuple(Seq<Type> ElementTypes) : Type;
public sealed record Function(Type ParameterType, Type ReturnType) : Type;
}
When to Use:
- Modeling domain concepts with fixed variants
- Need exhaustive pattern matching
- Immutability required
When to Avoid:
- Open-ended extensibility needed (use interface/abstract class)
- Many variants (>15) might indicate over-modeling
Related Patterns:
- Generic Attributes Pattern
- Wrapper Types (AccessControlled, Documented)
Pattern 2: Railway-Oriented Programming
Category: Functional Programming Frequency: High (used in IR validation, CLI tools) Complexity: Medium
Problem: Need explicit error handling without exceptions, composable validation chains.
Solution:
type Result<'T, 'Error> =
| Ok of 'T
| Error of 'Error
let (>>=) result f =
match result with
| Ok value -> f value
| Error err -> Error err
// Usage
let validateIR ir =
Ok ir
>>= validateDistribution
>>= validatePackages
>>= validateModules
When to Use:
- Validation pipelines
- Transformation chains that can fail
- Need to short-circuit on first error
When to Avoid:
- Need to collect all errors (use Applicative Validation)
- Performance-critical paths (exceptions may be faster)
Related Patterns:
- Result Monad
- Applicative Validation
Pattern 3: Lens Composition for Nested Updates
Category: Functional Programming Frequency: Medium (manual usage, pending generator) Complexity: High
Problem: Updating deeply nested immutable structures is verbose and error-prone.
Solution:
type Lens<'S, 'A> = {
Get: 'S -> 'A
Set: 'A -> 'S -> 'S
}
let (>>>) outer inner = {
Get = fun s -> inner.Get (outer.Get s)
Set = fun a s -> outer.Set (inner.Set a (outer.Get s)) s
}
// Usage
let personCityLens = addressLens >>> cityLens
let updated = Lens.set personCityLens "Shelbyville" person
When to Use:
- Deep nesting (3+ levels)
- Frequent updates to same paths
- Composable update logic needed
When to Avoid:
- Simple 1-2 level updates (use
withexpressions) - One-off updates (not worth the overhead)
Related Patterns:
- Optics (Prisms, Traversals)
- Myriad Lens Generator (future)
{Additional patterns documented in knowledge bases...}
Automation Scripts
Location: .claude/skills/morphir-architect/scripts/
Script 1: architecture-review.fsx
Purpose: Scan codebase for architectural anti-patterns and generate review report Token Savings: ~5000 tokens per review (vs manual scanning)
Usage:
dotnet fsi .claude/skills/morphir-architect/scripts/architecture-review.fsx
Output:
- Markdown review report
- Findings categorized by severity
- Recommendations with file/line references
Script 2: ir-consistency-check.fsx (future)
Purpose: Verify Classic IR and Modern IR are in sync Token Savings: ~2000 tokens per check
Usage:
dotnet fsi .claude/skills/morphir-architect/scripts/ir-consistency-check.fsx
Output:
- List of types present in one IR but not the other
- Conversion function coverage analysis
Script 3: pattern-matcher.fsx (future)
Purpose: Identify applicable design patterns in user code Token Savings: ~3000 tokens per analysis
Usage:
dotnet fsi .claude/skills/morphir-architect/scripts/pattern-matcher.fsx --file src/MyModule.fs
Output:
- Detected patterns
- Recommended refactorings
- Pattern application examples
Integration Points
Coordination with Other Skills
Technical Writer:
- Direction: to/from this skill
- Interaction: Architecture diagrams, pattern documentation
- Trigger: New patterns discovered, ADR updates
- Protocol: Architect defines structure, writer creates diagrams and docs
QA Tester:
- Direction: from this skill
- Interaction: Test strategies for FP code, property-based testing
- Trigger: New IR types, transformation pipelines
- Protocol: Architect provides invariants, QA creates tests
AOT Guru:
- Direction: to/from this skill
- Interaction: Pattern selection for AOT compatibility
- Trigger: Reflection-heavy patterns proposed
- Protocol: Architect consults on pattern trade-offs, AOT guru validates
Elm-to-F# Guru:
- Direction: to this skill
- Interaction: Elm pattern translation to F# idioms
- Trigger: New Elm patterns from morphir-elm
- Protocol: Elm guru identifies patterns, Architect adapts for F#/C#
Escalation Paths
When to Escalate:
- Fundamental IR design changes (breaking changes)
- New language features requiring core architecture updates
- Conflicting pattern recommendations (trade-off decisions)
How to Escalate:
- Document the architectural decision point
- Provide options with trade-off analysis
- Tag maintainer: @DamianReeves
- Label issue:
architecture,maintainer-attention - Wait for guidance before proceeding
What NOT to Decide:
- Breaking changes to public IR API
- Major paradigm shifts (e.g., mutable IR)
- Removing core patterns without migration path
Feedback Loop
Feedback Capture
Trigger Points:
- After each architectural guidance session
- Quarterly pattern review
- When new patterns discovered in codebase
- After major IR refactorings
Capture Method:
- Update MAINTENANCE.md with learnings
- Add new patterns to catalog
- Update knowledge bases with real examples
- Document anti-patterns discovered
What to Capture:
- Patterns applied successfully
- Patterns that didn't fit (and why)
- New pattern combinations
- Performance insights
- F#/C# interop challenges
Quarterly Review Process
Schedule: Q1, Q2, Q3, Q4
Review Checklist:
- [ ] Review all architectural decisions made
- [ ] Identify 2-3 key improvements for knowledge bases
- [ ] Update pattern catalog with new discoveries
- [ ] Analyze F#/C# interop pain points
- [ ] Evaluate code generator implementations (Myriad, Source Generators)
- [ ] Update playbooks based on learnings
- [ ] Bump version if user-facing changes
- [ ] Notify team of architectural guidance updates
Improvement Triggers:
- Pattern applied 3+ times → Add to catalog
- Anti-pattern discovered → Document in KB
- New Morphir version → Review IR changes
- Community feedback → Incorporate insights
Cross-Agent Compatibility
For Claude Code Users
Invocation:
@skill morphir-architect
Design an AST for representing Morphir function definitions
or
@skill architect
How should I implement a transformation pipeline with error handling?
Triggers: Keywords like "architecture", "design patterns", "AST", "IR", "functional programming", "monad", "lens", "visitor", "code generation"
For GitHub Copilot Users
Access:
- Read knowledge bases in
.agents/kbs/ - Run review scripts:
dotnet fsi .claude/skills/morphir-architect/scripts/*.fsx - Follow decision trees and playbooks in skill.md
- Reference pattern catalog for examples
Quick Start:
# Review architecture
dotnet fsi .claude/skills/morphir-architect/scripts/architecture-review.fsx
# Reference knowledge bases
cat .agents/kbs/language-design-patterns.md
cat .agents/kbs/functional-programming-patterns.md
For Other Agents (Cursor, Windsurf, Aider)
Access:
- Documentation:
.claude/skills/morphir-architect/skill.md(this file) - Quick reference:
.claude/skills/morphir-architect/README.md - Knowledge bases:
.agents/kbs/*.md - Scripts:
.claude/skills/morphir-architect/scripts/
Usage:
- Read skill.md for comprehensive guidance
- Reference knowledge bases for pattern details
- Follow playbooks for architectural workflows
- Use decision trees for pattern selection
- Run scripts for automated reviews
Templates
Location: .claude/skills/morphir-architect/templates/
Template 1: new-ast-type.md
Purpose: Template for designing new AST/IR types When to Use: Creating new node types for Morphir IR or custom ASTs
Usage:
- Copy template:
cp .claude/skills/morphir-architect/templates/new-ast-type.md . - Fill in type variants, attributes, operations
- Implement in F# or C# following template guidance
Template 2: transformation-pipeline.md
Purpose: Template for Railway-Oriented Programming pipelines When to Use: Building validation or transformation chains
Usage:
- Copy template:
cp .claude/skills/morphir-architect/templates/transformation-pipeline.md . - Define error types and validation steps
- Implement using Result monad
Template 3: visitor-implementation.md
Purpose: Template for implementing visitor patterns When to Use: Need systematic AST traversal or transformation
Usage:
- Copy template:
cp .claude/skills/morphir-architect/templates/visitor-implementation.md . - Choose variant (OO, functional, record-based)
- Implement for target AST types
Related Resources
Within This Project:
- [README.md](./README.md) - Quick reference guide
- [MAINTENANCE.md](./MAINTENANCE.md) - Maintenance and evolution guide
- [metadata.yaml](./metadata.yaml) - Skill metadata and configuration
Knowledge Bases:
- [Ecosystem Knowledge Base](../../../.agents/kbs/ecosystem-knowledge-base.md) - 50+ ecosystem entries
- [Language Design Patterns](../../../.agents/kbs/language-design-patterns.md) - 22+ AST/type system patterns
- [Visitor Pattern Implementations](../../../.agents/kbs/visitor-pattern-implementations.md) - 8 visitor variants
- [Computation Expressions for AST](../../../.agents/kbs/computation-expressions-for-ast.md) - CE patterns
- [Functional Programming Patterns](../../../.agents/kbs/functional-programming-patterns.md) - 18 FP patterns
- [Compiler Services & Metaprogramming](../../../.agents/kbs/compiler-services-metaprogramming.md) - Code generation
Project Guidance:
- [AGENTS.md](../../../AGENTS.md) - Primary agent guidance
- [CLAUDE.md](../../../CLAUDE.md) - Claude Code-specific instructions
- [Architectural Decisions](../../../.agents/decisionlogs/architectural-decisions.md) - 25 ADRs
- [Skills Reference](../../../.agents/skills-reference.md) - All available skills
External Resources:
- Morphir Homepage - Official Morphir documentation
- morphir-elm - Reference implementation
- F# for Fun and Profit - FP patterns and ROP
- Category Theory for Programmers - Theoretical foundations
Last Updated: 2025-12-24 Version: 1.0.0-alpha Status: alpha Maintainer: Damian Reeves (@DamianReeves)