ktsu.Semantics.Quantities
3.0.0
Prefix Reserved
See the version list below for details.
dotnet add package ktsu.Semantics.Quantities --version 3.0.0
NuGet\Install-Package ktsu.Semantics.Quantities -Version 3.0.0
<PackageReference Include="ktsu.Semantics.Quantities" Version="3.0.0" />
<PackageVersion Include="ktsu.Semantics.Quantities" Version="3.0.0" />
<PackageReference Include="ktsu.Semantics.Quantities" />
paket add ktsu.Semantics.Quantities --version 3.0.0
#r "nuget: ktsu.Semantics.Quantities, 3.0.0"
#:package ktsu.Semantics.Quantities@3.0.0
#addin nuget:?package=ktsu.Semantics.Quantities&version=3.0.0
#tool nuget:?package=ktsu.Semantics.Quantities&version=3.0.0
ktsu.Semantics.Quantities
A metadata-generated, type-safe physical quantity system built on a unified vector model, with compile-time dimensional analysis, generated unit conversions and physics operators, and centralized physical constants.
ktsu.Semantics.Quantities is one package in the ktsu.Semantics family. If you use a single numeric storage type throughout a project, the alias packages ktsu.Semantics.Quantities.Double, .Float, and .Decimal let you drop the generic argument and write Mass instead of Mass<double>.
Introduction
ktsu.Semantics.Quantities gives you physical quantities as types, so a Force cannot be added to a Speed and multiplying a Mass by an AccelerationMagnitude yields a ForceMagnitude at compile time. Every quantity is generic over its numeric storage type (Mass<double>, Speed<float>, Length<decimal>), and all values are stored in SI base units.
The type surface is generated. A single source of truth, dimensions.json, drives a Roslyn incremental generator that emits the quantity records, their From{Unit} factories with built-in conversions, the cross-dimensional physics operators, and the physical constants. That is roughly 72 physical dimensions and over 200 generated quantity types, all committed to source so the project compiles without first running the generator.
Every quantity is a vector, and the dimensionality of its direction space is part of the type.
| Form | Meaning | Sign | Examples |
|---|---|---|---|
IVector0 |
magnitude only | always >= 0 |
Speed, Mass, Energy, Distance, Area |
IVector1 |
signed 1D | signed | Velocity1D, Force1D, Temperature |
IVector2 |
2D directional | per-component | Velocity2D, Force2D, Acceleration2D |
IVector3 |
3D directional | per-component | Velocity3D, Force3D, Position3D |
IVector4 |
4D directional | per-component | reserved (relativistic / spacetime) |
IVectorN.Magnitude() (for N >= 1) returns the matching IVector0 quantity.
Features
- Compile-time dimensional safety: illegal combinations do not compile, and cross-dimensional operators produce the correct result type.
- Generated unit conversions:
From{Unit}factories per declared unit (Mass.FromKilogram,Speed.FromMeterPerSecond,Length.FromFoot), converting to the SI base unit on construction, withIn(unit)to convert back. - Unified vector model:
IVector0throughIVector4, withMagnitude(),Dot,Cross,Normalize, and typed cross-quantity results (Force3D.Dot(Displacement3D)returnsEnergy). - Construction-time invariants:
IVector0magnitudes are guarded non-negative, and quantities where zero is unphysical (Wavelength,Period,HalfLife) are guarded strictly positive. - Physical constants:
PhysicalConstantswith domain-groupedPreciseNumbervalues and generic accessors that materialize into anyT : INumber<T>. - Generator diagnostics: metadata problems (
SEM001-SEM005) are caught at build time.
Installation
Package Manager Console
Install-Package ktsu.Semantics.Quantities
.NET CLI
dotnet add package ktsu.Semantics.Quantities
Package Reference
<PackageReference Include="ktsu.Semantics.Quantities" Version="x.y.z" />
For a project that uses one storage type everywhere, reference an alias package instead (or in addition) so you can omit the generic argument. See storage-type aliases.
Usage Examples
Basic Example: magnitudes and operators
using ktsu.Semantics.Quantities;
Mass<double> m = Mass<double>.FromKilogram(2.0);
Speed<double> v = Speed<double>.FromMeterPerSecond(3.0);
MomentumMagnitude<double> p = m * v; // Mass * Speed -> MomentumMagnitude
double kg = m.Value; // stored SI-base value
// arithmetic and comparison are inherited
Speed<double> faster = v + Speed<double>.FromMeterPerSecond(5.0);
bool ok = faster > v;
// construction-time guard: a negative magnitude throws ArgumentException
// Speed<double>.FromMeterPerSecond(-1.0);
Vector quantities
using ktsu.Semantics.Quantities;
Force3D<double> f = new() { X = 3.0, Y = 4.0, Z = 0.0 };
ForceMagnitude<double> mag = f.Magnitude(); // matching Vector0 quantity, value 5.0
Force3D<double> unit = f.Normalize();
Displacement3D<double> d = new() { X = 1.0, Y = 0.0, Z = 0.0 };
Energy<double> work = f.Dot(d); // typed dot: Force . Displacement = Energy
Torque3D<double> torque = f.Cross(d); // typed cross: Force x Displacement = Torque
Momentum3D<double> impulse = f * Duration<double>.Create(2.0);
Physical constants
using ktsu.Semantics.Quantities;
// domain-grouped, exact PreciseNumber values
var c = PhysicalConstants.Fundamental.SpeedOfLight; // 299_792_458 m/s
var R = PhysicalConstants.Chemistry.GasConstant; // 8.31446... J/(mol.K)
// generic accessors materialize into any T : INumber<T>
double g = PhysicalConstants.Generic.StandardGravity<double>(); // 9.80665
ForceMagnitude<double> weight = Mass<double>.FromKilogram(70.0) * AccelerationMagnitude<double>.Create(g);
API Reference
Hand-written runtime types
| Type | Description |
|---|---|
SemanticQuantity<TSelf, T> |
Arithmetic base. Create(T) factory, Quantity value, and inherited + - * / - operators. Divide by zero throws DivideByZeroException. |
PhysicalQuantity<TSelf, T> |
Abstract base for scalar quantities. Adds Value, Dimension, IsPhysicallyValid, comparison operators, and cross-dimension-aware CompareTo/Equals. |
IVector0<TSelf, T> |
Magnitude-only marker: Value, static Zero. Non-negative by construction. |
IVector1<TSelf, T> |
Signed single-axis: Value, static Zero. |
IVector2 / IVector3 / IVector4 |
Directional vectors with X/Y/Z/W, Length(), LengthSquared(), Dot, Distance, Normalize; IVector3 adds Cross. |
Vector0Guards |
EnsureNonNegative(value, name) and EnsurePositive(value, name), used by generated From{Unit} factories. |
UnitSystem |
enum classifying units (SIBase, SIDerived, Metric, Imperial, ...). |
Generated quantity types
Each generated quantity is a partial record Name<T> where T : struct, INumber<T>. A typical IVector0 quantity such as Mass<T> exposes:
| Member | Description |
|---|---|
From{Unit}(T) |
e.g. FromKilogram, FromGram, FromPound. Converts to SI base and applies the guard. |
Create(T) |
Inherited base factory (value already in SI base units). |
Value |
The stored SI-base value. |
In(unit) |
Convert the value back to a specific unit. |
| typed operators | e.g. Mass * AccelerationMagnitude -> ForceMagnitude, Mass / Volume -> Density. |
Vector quantities (Force3D<T>, Velocity2D<T>, ...) implement the matching IVectorN and add Magnitude() (returning the corresponding *Magnitude Vector0 quantity), Dot, Cross, and typed cross-quantity results.
Factory names use the singular lemma of each unit name verbatim (FromMeterPerSecond, FromRevolutionPerMinute). There is no pluralization step.
PhysicalConstants
- Domain-grouped: nested static classes returning
PreciseNumber, for examplePhysicalConstants.Fundamental.SpeedOfLight,PhysicalConstants.ClassicalMechanics.StandardGravity,PhysicalConstants.Thermodynamics.WaterTriplePoint. Domain groups include Acoustics, AngularMechanics, Chemistry, ClassicalMechanics, FluidMechanics, Fundamental, NuclearPhysics, Optics, and Thermodynamics. - Generic:
PhysicalConstants.Generic.Name<T>()materializes any constant into aT : INumber<T>.
Architecture
The system is metadata-driven. The single source of truth is Semantics.SourceGenerators/Metadata/dimensions.json (alongside units.json, magnitudes.json, conversions.json, domains.json, and logarithmic.json). A Roslyn incremental generator emits one record per quantity, a From{Unit} factory per declared unit, the cross-dimensional * / / / Dot / Cross operators declared in the metadata, and the PhysicalConstants surface. Logarithmic-scale quantities (decibels, cents, pH) are generated separately because they do not obey linear arithmetic.
Generated output is committed to Generated/, so the project compiles without first running the generator. For the full design and an end-to-end "add a dimension" walk-through, see:
Contributing
Contributions are welcome! Feel free to open issues or submit pull requests.
License
This project is licensed under the MIT License. See the LICENSE.md file for details.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. 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. |
-
net10.0
- ktsu.PreciseNumber (>= 1.7.27)
-
net8.0
- ktsu.PreciseNumber (>= 1.7.27)
-
net9.0
- ktsu.PreciseNumber (>= 1.7.27)
NuGet packages (4)
Showing the top 4 NuGet packages that depend on ktsu.Semantics.Quantities:
| Package | Downloads |
|---|---|
|
ktsu.ImGuiNodeEditor
A comprehensive .NET library suite for building desktop applications with Dear ImGui. Provides application scaffolding with PID-controlled frame limiting, custom widgets (TabPanel, SearchBox, Knob, RadialProgressBar, DividerContainer, Grid), modal dialogs (file browser, input prompts, searchable lists), a theming system with 50+ built-in themes and scoped styling, and an attribute-based node graph editor with physics-based layout. Built on Hexa.NET.ImGui bindings and Silk.NET for cross-platform windowing. |
|
|
ktsu.Semantics.Quantities.Double
A comprehensive .NET library for replacing primitive obsession with strongly-typed, self-validating domain models across four pillars: semantic strings with 50+ validation attributes, polymorphic path handling, metadata-generated semantic quantities, and musical value types. The quantity system covers 60+ physical dimensions and 200+ generated types under a unified vector model, with compile-time dimensional safety, generated unit conversions and physics relationships, centralized physical constants, and optional per-storage-type alias packages. The music types provide type-safe pitches, intervals, scales and modes, chords with symbol parsing and voicing, keys with roman-numeral analysis, and rational durations and time signatures. Features factory-pattern and dependency-injection support for building robust, maintainable scientific and domain-specific applications. |
|
|
ktsu.Semantics.Quantities.Decimal
A comprehensive .NET library for replacing primitive obsession with strongly-typed, self-validating domain models across four pillars: semantic strings with 50+ validation attributes, polymorphic path handling, metadata-generated semantic quantities, and musical value types. The quantity system covers 60+ physical dimensions and 200+ generated types under a unified vector model, with compile-time dimensional safety, generated unit conversions and physics relationships, centralized physical constants, and optional per-storage-type alias packages. The music types provide type-safe pitches, intervals, scales and modes, chords with symbol parsing and voicing, keys with roman-numeral analysis, and rational durations and time signatures. Features factory-pattern and dependency-injection support for building robust, maintainable scientific and domain-specific applications. |
|
|
ktsu.Semantics.Quantities.Float
A comprehensive .NET library for replacing primitive obsession with strongly-typed, self-validating domain models across four pillars: semantic strings with 50+ validation attributes, polymorphic path handling, metadata-generated semantic quantities, and musical value types. The quantity system covers 60+ physical dimensions and 200+ generated types under a unified vector model, with compile-time dimensional safety, generated unit conversions and physics relationships, centralized physical constants, and optional per-storage-type alias packages. The music types provide type-safe pitches, intervals, scales and modes, chords with symbol parsing and voicing, keys with roman-numeral analysis, and rational durations and time signatures. Features factory-pattern and dependency-injection support for building robust, maintainable scientific and domain-specific applications. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 3.2.5 | 0 | 9/3/2026 |
| 3.2.4 | 50 | 9/2/2026 |
| 3.2.3 | 117 | 9/1/2026 |
| 3.2.2 | 159 | 8/31/2026 |
| 3.2.1 | 163 | 8/28/2026 |
| 3.2.0 | 217 | 8/27/2026 |
| 3.1.4 | 292 | 8/25/2026 |
| 3.1.3 | 261 | 8/24/2026 |
| 3.1.2 | 219 | 8/21/2026 |
| 3.1.1 | 260 | 8/19/2026 |
| 3.1.0 | 186 | 8/19/2026 |
| 3.0.1 | 137 | 8/18/2026 |
| 3.0.0 | 230 | 8/15/2026 |
| 2.9.14 | 248 | 8/14/2026 |
| 2.9.13 | 135 | 8/14/2026 |
| 2.9.12 | 138 | 8/14/2026 |
| 2.9.11 | 140 | 8/14/2026 |
| 2.9.10 | 133 | 8/14/2026 |
| 2.9.9 | 131 | 8/14/2026 |
| 2.9.8 | 144 | 8/14/2026 |
## v3.0.0 (major)
Changes since v2.0.0:
- [major] Sonar: clear all 24 open issues and the one security hotspot ([@matt-edmondson](https://github.com/matt-edmondson))
- [patch] MSTEST0058/0061: fix the two MSTest analyzer diagnostics ([@matt-edmondson](https://github.com/matt-edmondson))
- [patch] S4136/S4144: group overloads and drop duplicate private factories ([@matt-edmondson](https://github.com/matt-edmondson))
- [patch] S3776: reduce cognitive complexity in seven methods ([@matt-edmondson](https://github.com/matt-edmondson))
- [patch] S3267: clear the last two generator loops ([@matt-edmondson](https://github.com/matt-edmondson))
- [patch] S1172: drop the last four unused generator parameters ([@matt-edmondson](https://github.com/matt-edmondson))
- [patch] S3267: simplify two generator loops with LINQ ([@matt-edmondson](https://github.com/matt-edmondson))
- [patch] S1192: name the literals the generators emit ([@matt-edmondson](https://github.com/matt-edmondson))
- [patch] Add a local SonarCloud check; simplify AdjustForContrast; test PatternValidationRule ([@matt-edmondson](https://github.com/matt-edmondson))
- [patch] Fix a sentence-case bug, harden the pattern regex, tidy the generator ([@matt-edmondson](https://github.com/matt-edmondson))
- [patch] Extract the shared delimiter-separated casing rules ([@matt-edmondson](https://github.com/matt-edmondson))
- [patch] Adopt ktsu.Sdk 2.27.0: KTSU0001 package references ([@matt-edmondson](https://github.com/matt-edmondson))
- Merge remote-tracking branch 'origin/main' into chore/sonarcloud-cleanup-2 ([@matt-edmondson](https://github.com/matt-edmondson))
- [patch] Cover the untested casing and relative-path branches ([@matt-edmondson](https://github.com/matt-edmondson))
- [patch] Cover PropertyTemplate shorthand; drop the duplicated const docs ([@matt-edmondson](https://github.com/matt-edmondson))
- [patch] S4136: group AsAbsolute overloads in the relative path types ([@matt-edmondson](https://github.com/matt-edmondson))
- [patch] Fix SonarCloud issues: S2223, S1192, S6610, S6580, S3358 ([@matt-edmondson](https://github.com/matt-edmondson))
- [patch] Fold the generator tests into Semantics.Test so their coverage is collected ([@matt-edmondson](https://github.com/matt-edmondson))
- [patch] Add source generator tests to cover the generator pipeline ([@matt-edmondson](https://github.com/matt-edmondson))
- [patch] MSTEST0037: use the intent-revealing assertions ([@matt-edmondson](https://github.com/matt-edmondson))
- [patch] MSTEST0068: CollectionAssert.AreEqual -> Assert.AreSequenceEqual ([@matt-edmondson](https://github.com/matt-edmondson))
- [patch] Migrate file headers to the one-line ktsu-dev form ([@matt-edmondson](https://github.com/matt-edmondson))
- [patch] Fix SonarCloud BLOCKER issues in test suite ([@matt-edmondson](https://github.com/matt-edmondson))
- Sync .serena\.gitignore ([@KtsuTools](https://github.com/KtsuTools))
- Sync .runsettings ([@KtsuTools](https://github.com/KtsuTools))
- Sync .editorconfig ([@KtsuTools](https://github.com/KtsuTools))
- Sync .gitattributes ([@KtsuTools](https://github.com/KtsuTools))
- Sync global.json ([@KtsuTools](https://github.com/KtsuTools))
- [minor] Return the root itself from AbsoluteDirectoryPath.Parent ([@matt-edmondson](https://github.com/matt-edmondson))
- [patch] Fix directory detection in SemanticRelativePath.Make ([@matt-edmondson](https://github.com/matt-edmondson))
- Make the new path tests platform-agnostic ([@matt-edmondson](https://github.com/matt-edmondson))
- Emit CRLF from the generators and re-enable package validation ([@matt-edmondson](https://github.com/matt-edmondson))
- [minor] Compare semantic strings by value and expose path values on interfaces ([@matt-edmondson](https://github.com/matt-edmondson))
- [minor] Add color adjustment operations across color spaces ([@matt-edmondson](https://github.com/matt-edmondson))
- [patch] Fix Oklch assertion in color cross-conversion tests ([@matt-edmondson](https://github.com/matt-edmondson))
- [minor] Add cross-space conversions between all color types ([@matt-edmondson](https://github.com/matt-edmondson))
- fix(music): use ValueTuple.GetHashCode instead of System.HashCode for netstandard2.0 compatibility ([@matt-edmondson](https://github.com/matt-edmondson))
- refactor(music): split Progression.TryParse into helpers to cut cognitive complexity and remove always-true check (SonarQube S3776/S2583) ([@matt-edmondson](https://github.com/matt-edmondson))
- docs(music): update examples and references for Parse/TryParse rename and chart-style progressions ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(music): chart-style Arrangement ToString + Parse/TryParse + structural equality ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(music): chart-style Section ToString + Parse/TryParse ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(music)!: replace bar-delimited Progression.Parse with chart-style ToString/Parse/TryParse + structural equality; migrate call sites ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(music): rename Form.FromPattern to Parse/TryParse, canonical ToString, structural equality ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(music): Rest canonical ToString + Parse/TryParse ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(music): Note canonical ToString + Parse/TryParse ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(music): ChordEvent canonical ToString + Parse/TryParse ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(music): canonical Chord ToString, TryParse, ParseRoot via Notation ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(music): Key canonical ToString + Parse/TryParse; roman-numeral accidental via Notation ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(music): Scale canonical ToString + Parse/TryParse ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(music): Tempo canonical ToString + Parse/TryParse ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(music): Velocity canonical ToString + Parse/TryParse ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(music): TimeSignature canonical ToString + Parse/TryParse ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(music): Duration canonical ToString + Parse/TryParse ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(music): Interval canonical ToString + Parse/TryParse ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(music): rename Mode.FromName to Parse/TryParse, canonical ToString ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(music): typed Pitch factory, rename FromName to Parse/TryParse, canonical ToString ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(music): typed PitchClass factory, Parse/TryParse, canonical ToString ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(music): add NoteLetter and Accidental enums ([@matt-edmondson](https://github.com/matt-edmondson))
- docs: implementation plan for music type-safe factories and canonical round-trip ToString ([@matt-edmondson](https://github.com/matt-edmondson))
- docs: revise music factories spec with canonical round-trip ToString and chart-style aggregate format ([@matt-edmondson](https://github.com/matt-edmondson))
- docs: design spec for music type-safe factories and Parse/TryParse convention ([@matt-edmondson](https://github.com/matt-edmondson))
- [patch] docs: add per-package READMEs and turn root README into a family index ([@matt-edmondson](https://github.com/matt-edmondson))
- docs(music): document the analysis aggregate layer ([@matt-edmondson](https://github.com/matt-edmondson))
- test(music): lock guard/coverage contracts; dedupe chromatic scale check ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(music): add Form pattern extraction and named-form recognition ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(music): add Arrangement container ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(music): add Section structural unit ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(music): add chromatic chord identification ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(music): add key inference by diatonic fit ([@matt-edmondson](https://github.com/matt-edmondson))
- docs(music): switch key inference to quality-weighted scoring ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(music): add cadence detection ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(music): add roman-numeral labeling and functional classification ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(music): add Progression.Parse bar-delimited chord syntax ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(music): add Progression core (construction, totals, empty rejection) ([@matt-edmondson](https://github.com/matt-edmondson))
- fix(music): drop CA1859 pragma; use IMusicalEvent helper in ChordEvent test ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(music): add ChordEvent harmonic event type ([@matt-edmondson](https://github.com/matt-edmondson))
- docs(music): implementation plan for analysis aggregate layer ([@matt-edmondson](https://github.com/matt-edmondson))
- docs(music): design spec for analysis aggregate layer ([@matt-edmondson](https://github.com/matt-edmondson))
- test(strings): add As<T> round-trip test for Uuid ([@matt-edmondson](https://github.com/matt-edmondson))
- docs(strings): reconcile spec As<T> test bullet with implemented roster ([@matt-edmondson](https://github.com/matt-edmondson))
- docs(strings): document Identifiers package in README ([@matt-edmondson](https://github.com/matt-edmondson))
- chore(strings): finalize Identifiers package and document it ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(strings): add JwtToken identifier type ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(strings): add Iban identifier type ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(strings): add Isbn identifier type ([@matt-edmondson](https://github.com/matt-edmondson))
- style(strings): add trailing newline to IsCreditCardNumberAttribute.cs ([@matt-edmondson](https://github.com/matt-edmondson))
- docs(strings): use pattern-matching form in Tasks 5-6 (IDE0078) ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(strings): add CreditCardNumber identifier type ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(strings): add Ulid identifier type ([@matt-edmondson](https://github.com/matt-edmondson))
- docs(strings): align plan Tasks 3-7 with repo conventions (ThrowsExactly, no using System, Ensure.NotNull) ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(strings): add Uuid identifier type ([@matt-edmondson](https://github.com/matt-edmondson))
- chore(strings): scaffold Semantics.Strings.Identifiers package ([@matt-edmondson](https://github.com/matt-edmondson))
- docs(strings): correct empty-string handling in spec; add implementation plan ([@matt-edmondson](https://github.com/matt-edmondson))
- docs(strings): spec for Semantics.Strings.Identifiers (Phase 0) ([@matt-edmondson](https://github.com/matt-edmondson))
- docs(color): correct Oklab round-trip tolerance note in plan ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(color): add NamedColors and gamma-regression tests ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(color): add Oklab mix, lerp, distance, and gradient ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(color): add WCAG luminance, contrast, and accessibility adjustment ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(color): add HSL and HSV conversions ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(color): add Oklab and Oklch perceptual spaces ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(color): add hex and byte conversions (sRGB-interpreted) ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(color): add Srgb space and gamma-correct sRGB<->linear boundary ([@matt-edmondson](https://github.com/matt-edmondson))
- docs(color): add semantic-domains roadmap, Semantics.Color spec and plan ([@matt-edmondson](https://github.com/matt-edmondson))
- style(color): strip UTF-8 BOM and add final newline (editorconfig) ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(color): scaffold Semantics.Color with canonical linear Color type ([@matt-edmondson](https://github.com/matt-edmondson))
- docs: cover Semantics.Music score primitives, frequency, inversions, roman parsing ([@matt-edmondson](https://github.com/matt-edmondson))
- [minor] feat(music): score primitives, frequency bridge, inversions/transpose, roman-numeral parsing ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(music): parse roman numerals back into chords (inverse of RomanNumeralOf) ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(music): add chord inversions and Transpose on Chord/Scale/Key ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(music): add Pitch<->frequency (A440) and interval cents ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(music): add score primitives (Velocity, Tempo, Note, Rest) with real-time conversion ([@matt-edmondson](https://github.com/matt-edmondson))
- Merge feature/semantics-music-types: musical value types ([@matt-edmondson](https://github.com/matt-edmondson))
- [minor] feat(music): musical value types (pitch, interval, scale, chord, key, duration) ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(music): add Key with roman-numeral function; spell chromatic degrees conventionally (flat-preference) ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(music): add Chord engine with parsing, tones, and voicing (full HeatDeathRomance vocabulary) ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(music): add TimeSignature with bar and beat durations ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(music): add rational Duration with arithmetic and dotted/tuplet support ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(music): add Scale and ScaleDegree with degree resolution ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(music): add Mode with full standard scale catalog (diatonic, jazz, symmetric, pentatonic) ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(music): add Interval with octave folding and pitch difference ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(music): add Pitch with MIDI/name conversion and transpose ([@matt-edmondson](https://github.com/matt-edmondson))
- feat(music): scaffold Semantics.Music with PitchClass ([@matt-edmondson](https://github.com/matt-edmondson))
- fix(packaging): unblock the 2.0 release pipeline [patch] ([@matt-edmondson](https://github.com/matt-edmondson))