Morphir.CodeGeneration.FSharp 0.4.0-alpha.1

Prefix Reserved
This is a prerelease version of Morphir.CodeGeneration.FSharp.
There is a newer prerelease version of this package available.
See the version list below for details.
dotnet add package Morphir.CodeGeneration.FSharp --version 0.4.0-alpha.1
                    
NuGet\Install-Package Morphir.CodeGeneration.FSharp -Version 0.4.0-alpha.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Morphir.CodeGeneration.FSharp" Version="0.4.0-alpha.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Morphir.CodeGeneration.FSharp" Version="0.4.0-alpha.1" />
                    
Directory.Packages.props
<PackageReference Include="Morphir.CodeGeneration.FSharp" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Morphir.CodeGeneration.FSharp --version 0.4.0-alpha.1
                    
#r "nuget: Morphir.CodeGeneration.FSharp, 0.4.0-alpha.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Morphir.CodeGeneration.FSharp@0.4.0-alpha.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Morphir.CodeGeneration.FSharp&version=0.4.0-alpha.1&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Morphir.CodeGeneration.FSharp&version=0.4.0-alpha.1&prerelease
                    
Install as a Cake Tool

FINOS - Incubating Slack Development Workflow Deployment Workflow CVE Scanning NuGet Version NuGet Core NuGet Tooling Proto Plugin <img src="https://github.com/finos/branding/blob/master/project-logos/active-project-logos/Morphir%20Logo/Horizontal/2020_Morphir_Logo_Horizontal.png?raw=true" width="450">

Morphir

Morphir is a library of tools that works to capture business logic as data.

For the first time, business logic can be shared, stored, translated and visualised, all with the reliability of standardisation ensured in the Morphir framework.

What is it?

A set of tools for integrating technologies. Morphir is composed of a library of tools that facilitate the digitisation of business logic into multiple different languages & platforms. The Morphir framework is unique too in that facilities elements of automation and conversion that were previously unavailable in the field of finance-tech.

Why is it important?

Makes business logic portable. Business logic digitised provides distinct advantages: capacity for movement across departments and fields & the ability to be converted to new languages and applications.

How does it work?

Defines a standard format for storing and sharing business logic. A clear set of standards and format is in-place from the input/output, allowing for coherent structure.

What are the benefits?

✔️ Eliminates technical debt risk

Refactoring code libraries is often a harmful and time-sensitive issue for businesses, Morphir ensure the standards introduced from input eliminate delays at deployment.

✔️ Increases agility

Adaptability and usability are key concepts of the Morphir framework, business logic can now move with the code, be easily understood and adopted, in an ever-developing eco-system.

✔️ Ensures correctness

Certifying that specified functions behave as intended from input to output is assured through the Morphir library / tool chain.

✔️ Disseminates information through automation

Morphir’s automated processing helps disseminate information which otherwise may not be understood or shared at all, a useful tool when brining elements of business logic to conversation outside of its immediate audience (i.e developers).

Morphir .NET

Provides tooling for the Morphir ecosystem and .NET libraries that can be used to help you work with Morphir.

The additive shared configuration libraries provide typed TOML, YAML, JSON/JSON5 documents, pure source resolution, named profiles, validation and winning origins without constructing the CLI. Morphir.Configuration.IO reads explicit files or supplied text and exposes bounded project/workspace discovery through native and in-memory trees. See the discovery guide for ProjectSystem.Discover, per-root/member ProjectSystem.Load, membership/selection, host boundaries and explicitly authorized machine sources. Existing Git-first artifact discovery, cache-only tooling and CI overlays keep their compatibility behavior. Shared inspection APIs and morphir config get/list/show/path/explain expose typed values, source reports, scoped queries and redacted explanations. The optional Microsoft adapter projects one resolved document with explicit/source-generated Options binding. See the CLI reference for read controls, JSON schema and exit codes. Shared editing services and morphir config set/unset provide typed, scoped TOML previews and writes, source-preserving changes, optimistic conflicts and explicit recovery ownership. Shared classic project migration and morphir project migrate provide loss-checked previews and guarded TOML adoption while retaining classic bytes. Shared workspace migration adds bounded inventory, verified membership and recoverable batch application through morphir workspace migrate [directory]. See the reader profile for syntax and provenance.

SDK libraries

Morphir.SDK.CSharp is an independent net10.0 runtime package with immutable C#/.NET public types. See the C# SDK guide for its bounded operation contract and package usage.

The in-memory C# generator lowers typed classic/v4 libraries with explicit numeric C# 14/15 profiles, immutable values, executable functions/patterns/record operations and public SDK bindings. Original business fixtures and the bounded modern package-host/trimming checks are verified under #474. Implementation #478 landed. The main specification and archived acceptance evidence landed in archive follow-up #480. Coordinator cleanup remains pending.

Generate C# through the existing CLI, with numeric profiles and a validated optional namespace:

morphir generate --input model.json --target csharp --output generated --option language-version=14 --option namespace=Example.Generated --json

The C# walkthrough builds and runs a fresh consumer against the immutable runtime. CLI implementation #482 landed; its main specification and archived evidence are synchronized in this follow-up. Archive PR landing and root-verified cleanup remain pending.

Getting Started

Building from source

All projects target .NET 10 LTS. Install the SDK pinned in global.json, or use mise install to install the tools in mise.toml. CI uses the same SDK pin.

VS Code users can run Dev Containers: Reopen in Container to use the Microsoft .NET SDK image in .devcontainer/Dockerfile. The SDK includes the C# and F# compilers. Renovate groups the container, global.json, and mise SDK updates together and keeps them on .NET 10 LTS. Moving to the next LTS major version requires an explicit baseline update.

./build.sh --target Test
./build.sh --target PackAll
./build.sh --target TestBuild

To compile classic Morphir model JSON into F#, see the Myriad getting-started article, plugin reference, and car rental tutorial. The runnable example covers inventory, reservation, pickup, return and billing with one generated F# file per module.

Quick Start

Install Morphir using one of the following methods:

Using proto (Recommended for multi-language toolchains):

# Install proto (if not already installed)
curl -fsSL https://moonrepo.dev/install/proto.sh | bash  # Linux/macOS
# or: irm https://moonrepo.dev/install/proto.ps1 | iex  # Windows

# Add Morphir plugin and install
proto plugin add morphir "source:https://github.com/finos/morphir-dotnet/releases/latest/download/morphir_plugin.wasm"
proto install morphir

Using Platform-Specific Install Scripts:

# Linux
curl -fsSL https://raw.githubusercontent.com/finos/morphir-dotnet/main/scripts/install-linux.sh | bash

# macOS
curl -fsSL https://raw.githubusercontent.com/finos/morphir-dotnet/main/scripts/install-macos.sh | bash

# Windows (PowerShell)
irm https://raw.githubusercontent.com/finos/morphir-dotnet/main/scripts/install-windows.ps1 | iex

Using .NET Tool (requires .NET SDK):

dotnet tool install -g Morphir

Verify Installation:

morphir --version

For detailed installation instructions and troubleshooting, see the Installation Guide.

Documentation

Building

This project uses Nuke for build orchestration, providing a strongly-typed, cross-platform build system written in C#.

Requirements

  • .NET SDK 10.0.403 or a later patch in the same feature band, as specified in global.json

Basic Commands

# First-time setup: Restore tools and dependencies
dotnet tool restore
./build.sh --target Restore

# Build the solution (default target)
./build.sh

# Run tests
./build.sh --target Test

# Run linting/formatting checks
./build.sh --target Lint

# Format code
./build.sh --target Format

# Run full CI pipeline (restore, build, test, lint)
./build.sh --target CI

# Show all available targets
./build.sh --help

Windows users: Use build.cmd or build.ps1 instead of ./build.sh

Configuration

You can set the build configuration using the --configuration parameter:

# Build in Debug mode
./build.sh --configuration Debug

# Run tests in Debug mode
./build.sh --target Test --configuration Debug

By default, commands use Release configuration.

Migration from Just

This project was recently migrated from Just to Nuke. See NUKE_MIGRATION.md for the complete migration guide and command mappings. The old justfile is preserved for reference.

Developing

The shared .NET SDK contract freezes the bounded operation signatures, scalar limits and independent expectations used by both SDK deliveries. See the fixture guide for the build command, schema and provenance. After building its test project, run the offline validator with:

dotnet exec tests/Morphir.SDK.Conformance.Tests/bin/Debug/net10.0/Morphir.SDK.Conformance.Tests.dll --maximum-parallel-tests 2

F# runtime consumers use Morphir.SDK.FSharp. Its namespace and runtime assembly remain Morphir.SDK, so existing generated source and runtime type identities remain valid. The legacy Morphir.SDK package depends on the canonical package and ships no runtime assembly. See the F# runtime migration guide for dependency selection and covered behavior corrections.

Project Structure

morphir-dotnet/
├── src/
│   ├── Morphir.Core/          # Core IR types and utilities
│   ├── Morphir.Tooling/       # Tooling infrastructure
│   └── Morphir/               # CLI application
├── tests/
│   ├── Morphir.Core.Tests/    # Unit tests for Core
│   ├── Morphir.Tooling.Tests/ # Unit tests for Tooling
│   └── Morphir.E2E.Tests/     # End-to-end tests (BDD/Gherkin)
├── build/
│   ├── _build.csproj          # Nuke build project
│   └── Build.cs               # Build orchestration (strongly-typed)
├── scripts/                   # Build and utility scripts (C# scripts)
├── build.sh/cmd/ps1           # Nuke bootstrap scripts
└── justfile                   # Legacy build commands (preserved for reference)

Development Workflow

  1. Restore dependencies:

    ./build.sh --target Restore
    
  2. Build the solution:

    ./build.sh --target Compile
    
  3. Run tests:

    ./build.sh --target Test
    
  4. Check code formatting:

    ./build.sh --target Lint
    
  5. Format code (if needed):

    # Unix/macOS
    ./build.sh --target Format
    
    # Windows
    build.cmd --target Format
    # or
    ./build.ps1 --target Format
    

Scripts

The project uses C# scripts (.cs files) for build automation, leveraging .NET 10's direct C# file execution. These scripts are located in the scripts/ directory:

  • publish-single-file.cs - Publishes trimmed single-file executables
  • publish-single-file-untrimmed.cs - Publishes untrimmed single-file executables
  • run-tests.cs - Runs unit tests
  • run-e2e-tests.cs - Runs end-to-end tests
  • generate-wolverine-code.cs - Generates Wolverine code

Note: The deprecated build-tool-dll.cs and pack-tool-platform.cs scripts have been removed. Use the Nuke build targets (PackTool, PublishTool) instead.

Build Commands

All Nuke build commands support both Unix/macOS (./build.sh) and Windows (build.cmd or ./build.ps1) bootstrap scripts. Examples below show both formats.

Building Libraries
# Unix/macOS: Pack library projects as NuGet packages
./build.sh --target PackLibs

# Windows
build.cmd --target PackLibs
# or
./build.ps1 --target PackLibs

# Pack all projects (libraries and tool)
./build.sh --target PackAll                  # Unix/macOS
build.cmd --target PackAll                   # Windows

# Specify configuration and version
./build.sh --target PackLibs --configuration Debug --version 1.2.3
build.cmd --target PackLibs --configuration Debug --version 1.2.3

# Custom output directory
./build.sh --target PackLibs --output-dir ./my-packages
build.cmd --target PackLibs --output-dir ./my-packages
Building Executables
# Build a trimmed single-file executable for a specific platform
./build.sh --target PublishSingleFile --rid linux-x64        # Unix/macOS
build.cmd --target PublishSingleFile --rid linux-x64         # Windows

# Build an AOT (ahead-of-time compiled) executable
./build.sh --target PublishExecutable --rid linux-x64
build.cmd --target PublishExecutable --rid linux-x64

# Build an untrimmed executable (larger, better for debugging)
./build.sh --target PublishSingleFileUntrimmed --rid win-x64
build.cmd --target PublishSingleFileUntrimmed --rid win-x64

# Common RIDs: linux-x64, linux-arm64, win-x64, osx-x64, osx-arm64

# With custom configuration and output directory
./build.sh --target PublishSingleFile --rid linux-x64 --configuration Debug --output-dir ./bin
build.cmd --target PublishSingleFile --rid linux-x64 --configuration Debug --output-dir ./bin
Building the Dotnet Tool
# Pack the Morphir CLI as a dotnet tool
./build.sh --target PackTool                                  # Unix/macOS
build.cmd --target PackTool                                   # Windows

# With version and output directory
./build.sh --target PackTool --version 2.0.0 --output-dir ./packages
build.cmd --target PackTool --version 2.0.0 --output-dir ./packages
Testing
# Run unit tests
./build.sh --target Test                                      # Unix/macOS
build.cmd --target Test                                       # Windows

# Run tests in Debug configuration
./build.sh --target Test --configuration Debug
build.cmd --target Test --configuration Debug

# Build E2E test project
./build.sh --target BuildE2ETests
build.cmd --target BuildE2ETests

# Run end-to-end tests
./build.sh --target TestE2E                                   # Unix/macOS
build.cmd --target TestE2E                                    # Windows

# Run E2E tests for specific executable type (aot, trimmed, untrimmed, or all)
./build.sh --target TestE2E --executable-type trimmed
build.cmd --target TestE2E --executable-type trimmed
Publishing to NuGet
# Publish library packages to NuGet.org
./build.sh --target PublishLibs --api-key YOUR_API_KEY       # Unix/macOS
build.cmd --target PublishLibs --api-key YOUR_API_KEY        # Windows

# Publish the Morphir CLI tool package to NuGet.org
./build.sh --target PublishTool --api-key YOUR_API_KEY
build.cmd --target PublishTool --api-key YOUR_API_KEY

# Publish all packages
./build.sh --target PublishAll --api-key YOUR_API_KEY
build.cmd --target PublishAll --api-key YOUR_API_KEY

# Publish to custom NuGet source
./build.sh --target PublishLibs --nuget-source https://custom-feed.com --api-key YOUR_KEY
build.cmd --target PublishLibs --nuget-source https://custom-feed.com --api-key YOUR_KEY

# Publish to local NuGet feed (for testing)
./build.sh --target PublishLocalLibs                          # Unix/macOS
build.cmd --target PublishLocalLibs                           # Windows

# With custom local source
./build.sh --target PublishLocalLibs --local-source ./my-local-feed
build.cmd --target PublishLocalLibs --local-source ./my-local-feed

# Install tool locally from package
./build.sh --target PublishLocalTool
build.cmd --target PublishLocalTool

# Install globally
./build.sh --target PublishLocalTool --global true
build.cmd --target PublishLocalTool --global true

Available Nuke Targets

Run ./build.sh --help (Unix/macOS) or build.cmd --help (Windows) to see all available targets with descriptions and parameters.

Key targets:

  • Restore - Restore .NET dependencies
  • Compile - Build the solution (default target)
  • Test - Run unit tests
  • Lint - Check code formatting
  • Format - Format code
  • CI - Run full CI pipeline (restore, build, test, lint)
  • PackLibs - Pack library projects as NuGet packages
  • PackTool - Pack the Morphir CLI as a dotnet tool
  • PackAll - Pack all projects (libraries and tool)
  • PublishSingleFile - Publish trimmed single-file executable (requires --rid)
  • PublishExecutable - Publish AOT executable (requires --rid)
  • PublishSingleFileUntrimmed - Publish untrimmed single-file executable (requires --rid)
  • TestE2E - Run end-to-end tests
  • PublishLibs - Publish library packages to NuGet
  • PublishTool - Publish tool package to NuGet
  • PublishAll - Publish all packages to NuGet
  • PublishLocalLibs - Publish libraries to local feed
  • PublishLocalTool - Install tool locally from package
  • PublishLocalAll - Publish all to local feed

Contributing

We welcome contributions! Please see our Contributing Guide for details.

License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

SDK runtime delivery and archival evidence is recorded in the runtime delivery record. The canonical C# runtime spec, F# package spec, and stable C# API handoff describe the landed runtimes. SDK archive #472 landed; source SDK worktrees and their owned artifacts were removed. Empty shared archive directory cleanup remains pending with the recorded permission/policy limitations.

OpenSpec change proposals

This repository uses the shared html-design OpenSpec workflow. New proposals produce capability specs, a standalone design.html, and implementation tasks. See the OpenSpec guide for setup, verification and updates.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Morphir.CodeGeneration.FSharp:

Package Downloads
Morphir.Tooling

Package Description

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.4.0-alpha.4 53 11/10/2026
0.4.0-alpha.3 59 11/9/2026
0.4.0-alpha.2 59 11/8/2026
0.4.0-alpha.1 64 11/7/2026

### Fixed

- The global Morphir home is no longer discovered as a project. Walking up from a directory under the home folder used to find `~/.morphir/morphir.toml` through the `.morphir/` layout and load it as both a global source and the project's primary. It now loads only as a global source ([#494](https://github.com/finos/morphir-dotnet/issues/494))
- A native Windows `MORPHIR_HOME` such as `C:/Users/me/.morphir` works. It was treated as relative and joined onto the current directory, so every `config` command failed with `discovery.read_error` ([#494](https://github.com/finos/morphir-dotnet/issues/494))
- Every Morphir assembly now takes its version from CHANGELOG.md, so assemblies no longer reference each other as `1.0.0.0`. An explicit `-p:Version` or `-p:PackageVersion` still wins, for local and test packages. Previously the packed `dotnet-morphir` tool failed `generate` with `Could not load file or assembly 'Morphir.Models, Version=1.0.0.0'`
- `Morphir.Tooling` and `Morphir` can now be installed from NuGet: releases also publish their dependencies `Morphir.Configuration`, `Morphir.Configuration.IO`, `Morphir.IR.Pipeline`, `Morphir.IR.Pipeline.Plugins`, `Morphir.Ion` and `Morphir.CodeGeneration.FSharp`. A build test now fails if a packed package depends on a Morphir package that is not packed
- GitHub releases now include the `morphir-{rid}-v{version}.tar.gz` archives that the proto plugin downloads, so `proto install morphir` works again
- The deployment workflow now requires the release version to be the latest release in CHANGELOG.md, which is the version the build stamps. The ignored `--version` arguments and the `--version-override` build parameter, which had no effect, are removed
- `morphir ir verify --json` no longer crashes in the standalone executables with `Reflection-based serialization has been disabled`; it now uses source-generated JSON serialization
- The deployment workflow's end-to-end tests run again. Their test filter was malformed and selected no tests, which hid an invalid step definition, a duplicate step definition and the `ir verify --json` crash
- `PublishLocalTool` installs from the local package directory again; it no longer fails on the repository's package source mapping
- The documentation site builds again: Docsy is pinned to v0.13.0 and Hugo to 0.169.0, after Docsy v0.18 moved its theme out of the module root
- F# `Decimal.fromString` roundtrips invariant SDK output under comma-decimal cultures while retaining unambiguous localized input; package migration checks also exercise a later release version ([#465](https://github.com/finos/morphir-dotnet/issues/465)).
- F# SDK arithmetic detects covered Int32 overflow; minimum-Int remainder/modulus by -1 return zero, direct string comparison uses ordinal UTF-16 order, dictionary union keeps the first value, and Decimal text is invariant without trailing fractional zeros. Added checked Float-to-Int rounding and optional `Decimal.div` while retaining existing public entry points ([#465](https://github.com/finos/morphir-dotnet/issues/465)).
- `VFileTree.writeToDisk` no longer writes outside the output directory. It returns `TreeWriteError.InvalidTree` and writes nothing for rooted or `..` paths, files with no path, and duplicate locations, and it no longer adds the root tree path to output paths (#376)
- `VFileTree.toFileMap` and `toStringMap` keys are now relative to the tree root and use forward slashes on every platform (#376)
- `VFileTree.findFile` and `updateFile` accept a file's full location, and `updateFile` no longer changes same-named files in other directories (#376)
- Claude Code skills now load correctly - renamed all `skill.md` files to `SKILL.md` (uppercase, case-sensitive requirement)
- Updated all skill documentation references to use correct `SKILL.md` filename
- **CRITICAL**: Removed contradictory Claude co-author example from AGENTS.md and strengthened CLA compliance warnings in both AGENTS.md and CLAUDE.md (issue #270)

### Added

- `MORPHIR_DISCOVERY_BOUNDARY` and `MORPHIR_ISOLATED` environment variables mirror `--discovery-boundary` and `--isolated` for the `config` commands, and `MORPHIR_DISCOVERY_BOUNDARY` also bounds `project migrate` and `workspace migrate`, which gains `--discovery-boundary`. A flag wins over its variable, which wins over the default. `--isolated` now accepts `true` or `false`, so a command can turn off isolation set in the environment, and `config path --json` reports the effective controls and their sources ([#494](https://github.com/finos/morphir-dotnet/issues/494))
- Shared test sandbox, child-process runner and machine tripwire in `tests/Morphir.TestSupport`, so tests stay off the developer's real Morphir configuration ([#494](https://github.com/finos/morphir-dotnet/issues/494))
- Synchronized both landed C# CLI deltas into the main specifications and archived all nine checked tasks; archive PR landing and coordinator cleanup remain pending ([#481](https://github.com/finos/morphir-dotnet/issues/481), [#482](https://github.com/finos/morphir-dotnet/pull/482)).
- Added exact `csharp` CLI generation with numeric 14/15 profiles, a validated optional namespace and the existing owned publication/reporting flow ([#481](https://github.com/finos/morphir-dotnet/issues/481)).
- Synchronized the landed C# generator's eight requirements and 19 scenarios into the main specification and prepared its 13-task OpenSpec archive; archive follow-up landing and coordinator cleanup remain pending ([#474](https://github.com/finos/morphir-dotnet/issues/474), [#478](https://github.com/finos/morphir-dotnet/pull/478)).
- Reusable in-memory C# generation for typed classic/v4 libraries with numeric 14/15 profiles, immutable structural values, executable functions/patterns/record operations, public SDK bindings, located whole-model refusals and traversal cancellation; compiled business/SDK observations and bounded modern package-host/trimming verification ([#474](https://github.com/finos/morphir-dotnet/issues/474)).
- Synchronized and archived the landed C# and F# SDK runtime specifications, with stable API handoff paths and separate runtime delivery evidence; archive PR #472 landed; empty archive-directory cleanup remains pending ([#464](https://github.com/finos/morphir-dotnet/issues/464), [#465](https://github.com/finos/morphir-dotnet/issues/465)).
- Independent immutable Morphir.SDK.CSharp runtime for the bounded .NET SDK contract, with checked scalars, persistent collections and public package consumer verification ([#464](https://github.com/finos/morphir-dotnet/issues/464))
- Canonical `Morphir.SDK.FSharp` runtime package and dependency-only `Morphir.SDK` compatibility package, preserving existing runtime identities, with packaged source/binary checks and the frozen F# conformance adapter ([#465](https://github.com/finos/morphir-dotnet/issues/465))
- Shared .NET SDK conformance contract, pinned source evidence, tagged offline corpus and fixture validator for the C# and F# SDK deliveries ([#460](https://github.com/finos/morphir-dotnet/issues/460))
- `Morphir.Ion` library project: reads Ion 1.0 text and binary into immutable values, and reads the MEP `morphir_model` document with `ModelDocument.readPayload`, `readFile` and `decodeIr`. Reading keeps the exact bytes, annotations, numeric exactness and unknown data, and decodes the classic or v4 IR only on request
- `IonIr.read` and `IonIrTree.read` read the draft Ion IR format `ionVersion` `0.1.0-draft.1` for IR 3.0.0, 3.1.0 and 4.0.0, from a single file or a document tree. `IonIrParser` plugs them into a pipeline
- `Morphir.IR.V4`, an immutable IR v4 model, with the JSON reader `V4Json` and strict name parsing in `CanonicalNames`
- `ClassicJson.readDistribution`, a public reader for complete classic IR JSON, including dependency specifications
- `VFileTree` usage and morphir-elm migration guide in the `Morphir.IR.Pipeline` README (#376)
- `VFileTree.fromFileMap` now infers nested directories from map keys (#376)
- `VFileTree.loadFromDisk` loads a directory into a tree, returning `Result<VFileTree, TreeLoadError>` (#376)
- `TreeWriteError`, `TreeWriteProblem` and `TreeLoadError` union types for file tree I/O failures, with `describe` functions for display (#376)
- `ParseError` union type, which keeps the rule, location and source position of malformed input on the resulting diagnostic
- Strongly typed pipeline: `Parser<'T>`, `Plugin<'T>`, `Compiler<'T>` and `MorphirProcessor<'T>` replace the `obj`-based contracts, and a run returns a `VFileTree`, so one input can produce many output files
- `MorphirProcessor.run` accepts a file or a directory, and `MorphirProcessor.runEachFile` runs once per file in a tree
- `Parser.forFile`, `Parser.ofParseable` and `Plugin.focus` for building typed stages
- `Property<'T>` and `PropertyBag`, a typed replacement for string-keyed data on files, trees, tree configuration and processors, with functions that work with `>`, `<` and `>>`
- `VFileContent` for text, bytes or a re-openable `StreamSource`, so file content does not have to be held in memory. `VFileTree.loadFromDisk` no longer reads files up front, and binary files survive a round trip
- Tree-level diagnostics on `VFileTree`, and `Path` and `Location` on `VMessage`, with `VMessage.describe` for display
- `VFileTree.publish`, `validatePublish`, `readManifest` and `declaredOrder`: path containment, symbolic link rejection, case-insensitive collision detection, staged publication, no rewriting of identical files, and manifest-based removal of obsolete files, moved from the Myriad build task so that every backend gets them
- `Morphir.CodeGeneration.FSharp` now runs as a real pipeline through `Transpiler.generate`, with scope validation, type validation and constant folding. Definite type mismatches now fail the build, and folded literals appear in generated source. `GeneratedModule` and `Diagnostic` are removed in favour of `VFileTree` and `VMessage`
- `Optimizer` and `TypeValidator` now process real packages: the optimizer matches SDK functions by fully qualified name and folds only where the result matches run-time behaviour, and the validator reports only definite mismatches
- **Morphir.SDK F# Runtime Library** (`Morphir.SDK` NuGet package)
- Comprehensive skills troubleshooting guide (`.claude/skills/TROUBLESHOOTING.md`)
- Cross-platform skill invocation documentation in `.agents/skills-reference.md` with platform-specific guidance for Claude Code, GitHub Copilot, Cursor, Windsurf, and JetBrains AI
- Skill alias documentation (documentation-only feature, not functionally supported)
- Session restart requirements documentation for Claude Code skills
- Agent capabilities comparison table showing feature support across platforms
- **CLA compliance guidance** in AGENTS.md with remediation steps for accidental Claude co-author inclusion
- **GitHub issue #270** for F# script to automatically remove Claude co-author from commit history

### Removed

- **BREAKING** (Morphir.Tooling API): `Morphir.Tooling.Configuration.ConfigResolver`, `WorkspaceDiscovery` and `TomlParser` are removed. They walked to the filesystem root and treated any `.git` or `.morphir` directory as a workspace, including the global Morphir home, and could not be contained. No restorable package release ever exposed them. Use `ProjectSystem.Discover` / `ProjectSystem.LoadDetailed` and the shared resolver; replace the legacy CI mode with a named profile selected by `--profiles` or `MORPHIR_PROFILES` ([#494](https://github.com/finos/morphir-dotnet/issues/494))

### Changed

- The `dist`, `tool` and `extension` sub-commands now fail with "not implemented yet", exit code 1 and a link to their tracking issue ([#490](https://github.com/finos/morphir-dotnet/issues/490), [#491](https://github.com/finos/morphir-dotnet/issues/491), [#492](https://github.com/finos/morphir-dotnet/issues/492)). Previously they printed a message and exited 0 without doing anything
- **BREAKING**: The classic `Distribution` has a `Specs` case for IR 3.1.0, and `Distribution.packageDefinition` returns an option because a `Specs` distribution has no definitions
- The classic JSON decoder moved from `Morphir.CodeGeneration.FSharp` to `Morphir.Models`. F# generation keeps its acceptance rules and diagnostics
- Ignore Reqnroll-generated `*.feature.cs` files per Reqnroll best practices
- Configure `ReqnrollUseIntermediateOutputPathForCodeBehind` in test projects to generate code-behind files to obj/ directory
- Refactored AGENTS.md skill invocation section - replaced verbose content (155 lines) with concise summary (29 lines) and link to detailed guide in skills-reference.md
- Enhanced skill template (`.claude/skills/template/SKILL.md`) with optional alias documentation in YAML frontmatter
- **Strengthened CLA warnings** in AGENTS.md and CLAUDE.md - made CRITICAL sections highly visible with remediation steps and reference to automated script (issue #270)