This document provides guidance for AI assistants and developers working on the Morphir project.
This repository contains:
- Morphir Documentation Website - Docusaurus-based documentation site
- Morphir Live - Rust-based interactive visualization and IR management application
- Morphir CLI - Command-line tool for working with Morphir IR
- Ecosystem Integration - Git submodules for ecosystem repos (morphir-rust, morphir-examples, etc.)
- finos/morphir-go - Go implementation of Morphir tooling
- finos/morphir-elm - Reference implementation in Elm (most mature)
- finos/morphir-jvm - JVM-based implementation
- finos/morphir-scala - Scala implementation
- finos/morphir-dotnet - .NET implementation
- finos/morphir-rust - Rust tooling
- finos/morphir-python - Python tooling
- finos/morphir-moonbit - MoonBit implementation of Morphir tooling
The Morphir IR specification and JSON schemas are available in the morphir-dotnet documentation. Always maintain alignment with the official IR specification when implementing features.
Functional programming is fundamental to this codebase. All code should follow functional programming principles:
- Immutable data structures - Prefer immutable types and avoid mutating state
- Pure functions - Functions should have no side effects when possible
- Separation of concerns - Clearly define I/O boundaries
- Functional composition - Build complex behavior from simple, composable functions
Write tests before implementation. Follow the TDD cycle:
- Write a failing test
- Write minimal code to make it pass
- Refactor while keeping tests green
- Write self-documenting code with clear names
- Keep functions small and focused
- Follow Rust conventions and idioms
- Organize code by feature/domain, not by technical layer
- Cargo workspace at repository root
- Crates located in
crates/directory - Edition 2024 with resolver v3
- dioxus - Cross-platform UI framework (web, desktop, mobile)
- clap - Command-line argument parsing with derive macros
- miette - Fancy diagnostic error reporting
- tracing - Structured, async-aware logging and diagnostics
- serde - Serialization/deserialization
- Use workspace dependencies for version consistency
- Prefer
miettefor user-facing errors with helpful diagnostics - Use
tracingmacros (info!,debug!,error!) instead ofprintln! - Follow Rust 2024 edition idioms
// CLI with clap
use clap::Parser;
#[derive(Parser)]
#[command(name = "morphir-live")]
struct Cli {
#[arg(short, long)]
verbose: bool,
}
// Error handling with miette
use miette::{Diagnostic, Result};
use thiserror::Error;
#[derive(Error, Diagnostic, Debug)]
#[error("Failed to parse IR")]
#[diagnostic(code(morphir::parse_error))]
struct ParseError {
#[source_code]
src: String,
#[label("here")]
span: (usize, usize),
}
// Structured logging with tracing
use tracing::{info, instrument};
#[instrument]
fn process_ir(path: &str) -> Result<()> {
info!(path, "Processing IR file");
// ...
Ok(())
}morphir/
├── crates/
│ ├── morphir/ # Morphir CLI tool
│ └── morphir-live/ # Interactive visualization app (Dioxus)
├── ecosystem/ # Git submodules for ecosystem repos
│ ├── morphir-rust/ # Rust libraries (morphir-core, morphir-common, etc.)
│ ├── morphir-examples/ # Example Morphir projects
│ ├── README.md # User guide for ecosystem submodules
│ └── AGENTS.md # Agent guidelines for ecosystem directory
├── website/ # Docusaurus documentation site
├── docs/ # Documentation content
├── examples/ # Example projects
├── Cargo.toml # Rust workspace configuration
└── .config/mise/ # Development task configuration
See ecosystem/AGENTS.md for guidelines on working with submodules and path dependencies.
Use mise task runner (mise run <task>) for build orchestration:
mise run init- Initialize development environment (submodules, etc.)mise run build- Build the projectmise run test- Run all testsmise run fmt- Format codemise run lint- Run linters (clippy)mise run dev- Run morphir-live in development modemise run submodules:init- Initialize git submodules (first-time setup)mise run submodules:update- Update submodules to recorded commitsmise run submodules:status- Show submodule statusmise run submodules:add -- <name> [url]- Add a new ecosystem submodule
Build and test ecosystem submodules from the top-level repo:
mise run build:morphir-moonbit- Build all MoonBit packagesmise run build:morphir-moonbit -- <pkg>- Build specific package(s)mise run test:morphir-moonbit- Run all MoonBit testsmise run test:morphir-moonbit -- <pkg>- Test specific package(s)
Valid package names: morphir-sdk, morphir-core, morphir-moonbit-bindings
-
Follow functional programming patterns
- Avoid mutable state
- Prefer pure functions
- Use functional composition
-
Write tests first (TDD)
- Start with failing tests
- Implement to make tests pass
- Refactor with confidence
-
Reference other Morphir implementations
- Check how similar features are implemented in other languages
- Maintain consistency with Morphir IR specification
ABSOLUTELY DO NOT include AI assistants (like Claude) as co-authors in commits.
This project is part of the FINOS foundation and uses EasyCLA for compliance.
- ❌ Adding AI co-authors breaks the CLA check
- ❌ This blocks pull requests from being merged
Correct approach:
git commit -m "feat: add new feature"INCORRECT approach (WILL BREAK EasyCLA):
git commit -m "feat: add new feature
Co-Authored-By: Claude <noreply@anthropic.com>"When monitoring GitHub PR checks (CI status, workflow runs, etc.), prefer using watch mode with timeout or failfast rather than performing a sleep and then checking.
Preferred approach:
- Use
gh pr checks watchor similar watch-mode commands with timeout/failfast flags - This provides real-time updates and exits as soon as checks complete or fail
- More efficient than polling with sleep intervals
Example:
# Watch PR checks with timeout
gh pr checks watch --timeout 30m --failfast
# Or watch specific workflow runs
gh run watch --timeout 20m --exit-statusAvoid:
- ❌
sleep 60 && gh pr checks(inefficient polling) - ❌ Manual polling loops with fixed delays
Watch mode provides better responsiveness and resource efficiency by reacting to state changes immediately rather than waiting for arbitrary time intervals.
The Docusaurus website is located in website/. To run locally:
cd website
npm install
npm startWhen in doubt:
- Check reference implementations (especially morphir-elm)
- Consult Morphir IR specification
- Follow functional programming principles
- Write tests first
- Keep code simple and composable
This project uses beads for issue tracking. Issues are stored in .beads/ and tracked in git.
bd ready # Show issues ready to work (no blockers)
bd list --status=open # All open issues
bd show <id> # Full issue details with dependencies
bd create --title="..." --type=task --priority=2
bd update <id> --status=in_progress
bd close <id>
bd sync # Commit and push changesBefore ending any session:
git status # Check what changed
git add <files> # Stage code changes
bd sync # Commit beads changes
git commit -m "..." # Commit code
git push # Push to remoteWhen ending a work session, you MUST complete ALL steps below. Work is NOT complete until git push succeeds.
MANDATORY WORKFLOW:
- File issues for remaining work - Create issues for anything that needs follow-up
- Run quality gates (if code changed) - Tests, linters, builds
- Update issue status - Close finished work, update in-progress items
- PUSH TO REMOTE - This is MANDATORY:
git pull --rebase bd sync git push git status # MUST show "up to date with origin" - Clean up - Clear stashes, prune remote branches
- Verify - All changes committed AND pushed
- Hand off - Provide context for next session
CRITICAL RULES:
- Work is NOT complete until
git pushsucceeds - NEVER stop before pushing - that leaves work stranded locally
- NEVER say "ready to push when you are" - YOU must push
- If push fails, resolve and retry until it succeeds