Skip to content

ktsu.Semantics 2.0.0 — Unified Vector Quantities [major]#102

Merged
matt-edmondson merged 109 commits into
mainfrom
vectors
Jun 27, 2026
Merged

ktsu.Semantics 2.0.0 — Unified Vector Quantities [major]#102
matt-edmondson merged 109 commits into
mainfrom
vectors

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

ktsu.Semantics 2.0.0 — Unified Vector Quantities

Major release of the semantic-quantity system. This is the vectors branch: a metadata-driven, source-generated rewrite of the physical-quantities library, plus the strings/paths components. Breaking — see docs/migration-guide-2.0.md.

Highlights

  • Unified vector model — every quantity is a vector (IVector0..IVector4); dimensionality of the direction space is part of the type. Generic over numeric storage (where T : INumber<T>).
  • Metadata-driven generatorSemantics.SourceGenerators emits quantity types, units, conversions, constants, and log-scales from dimensions.json / units.json / domains.json / logarithmic.json. Diagnostics SEM001–SEM005.
  • Generated PhysicalConstants from domains.json (domain-grouped PreciseNumber + generic T accessors).
  • Storage-type alias packagesktsu.Semantics.Quantities.{Double,Float,Decimal} ship buildTransitive props so consumers write Mass instead of Mass<double>.
  • Logarithmic scales (decibels, cents/semitones, pH) generated from logarithmic.json.

Release-readiness (verified locally on the merged state)

  • dotnet build -c Release0 warnings, 0 errors
  • dotnet test782 passed, 0 failed
  • Generated sources + alias props regenerate identically (verify-generated gate passes)
  • Merged latest main (template syncs incl. ktsu.Sdk 2.11.0)

Fixes made while preparing the release

  • Cleared a stray CS8600 in LogarithmicScalesGenerator.
  • Restored icon.png as an LFS pointer after the main merge regressed it to raw bytes.
  • Dropped unreferenced Microsoft.SourceLink.* package versions (new KTSU0005 analyzer under ktsu.Sdk 2.11.0).

Versioning

Tagged [major] so the KtsuBuild pipeline releases 2.0.0 on merge to main. Closes #59 and #61 (resolved on this branch).

matt-edmondson and others added 30 commits August 3, 2025 22:45
This commit includes significant updates across various quantity classes, including:
- Refactoring of existing classes for improved structure and consistency.
- Enhancements to unit tests for better coverage and reliability.
- Updates to documentation and comments for clarity.

These changes aim to improve the maintainability and performance of the codebase while ensuring that the tests accurately reflect the expected behavior of the quantity classes.
…al, fluid dynamics, mechanics, nuclear, optical, and thermal domains

This commit introduces new classes and methods for various physical quantities, including:
- Acoustic properties such as AcousticImpedance, DirectionalityIndex, and SoundPressure.
- Chemical properties including ActivationEnergy, Concentration, and pH.
- Electrical properties like ElectricCapacitance, ElectricCurrent, and ElectricResistance.
- Fluid dynamics quantities such as BulkModulus and ReynoldsNumber.
- Mechanics quantities including Acceleration, Force, and Mass.
- Nuclear properties like AbsorbedDose and RadioactiveActivity.
- Optical properties such as Illuminance and LuminousIntensity.
- Thermal properties including Heat, Temperature, and ThermalConductivity.

Each class includes methods for creating instances from specific units, enhancing the usability and functionality of the library.
…emical, electrical, fluid dynamics, mechanics, nuclear, optical, and thermal domains

This commit introduces static factory methods for creating instances of various quantity classes from specific units, enhancing usability. The following methods were added:
- Acoustic: FromDirectivityFactor, FromMegahertz, FromPhons, etc.
- Chemical: FromKatal, FromGramsPerMole, FromPascalSeconds, etc.
- Electrical: FromFarads, FromCoulombs, FromOhms, etc.
- Fluid Dynamics: FromSquareMetersPerSecond, FromKilogramsPerSecond, etc.
- Mechanics: FromNewtons, FromKilogramSquareMeters, FromPascals, etc.
- Nuclear: FromSieverts, FromCoulombsPerKilogram, etc.
- Optical: FromLux, FromCandelaPerSquareMeter, etc.
- Thermal: FromJoules, FromKelvin, FromWattsPerSquareMeterKelvin, etc.

These enhancements improve the functionality and clarity of the library.
This commit introduces new extension methods for creating physical quantities from numeric values in both double and float types. The following categories are included:
- Length, Mass, Time, Area, Volume, Energy, Power, Force, Pressure, and more.
- Each category provides factory methods for common units, enhancing usability and supporting unit conversions.

Additionally, several existing methods in chemical quantity classes have been updated to remove unnecessary 'new' keywords, improving code clarity and consistency.
…rious domains

This commit adds static factory methods for creating instances of float quantity classes in acoustic, chemical, electrical, fluid dynamics, mechanics, nuclear, optical, and thermal domains. Methods include:
- Acoustic: FromRayls, FromDirectivityFactor, FromMegahertz, etc.
- Chemical: FromJoulesPerMole, FromMoles, FromPascalSeconds, etc.
- Electrical: FromFarads, FromCoulombs, FromOhms, etc.
- Fluid Dynamics: FromSquareMetersPerSecond, FromKilogramsPerSecond, etc.
- Mechanics: FromNewtons, FromKilogramSquareMeters, FromPascals, etc.
- Nuclear: FromSieverts, FromCoulombsPerKilogram, etc.
- Optical: FromLux, FromCandelaPerSquareMeter, etc.
- Thermal: FromJoules, FromKelvin, FromWattsPerSquareMeterKelvin, etc.

These enhancements improve usability and support unit conversions for float quantities.
…reating instances from nanometers and molar concentrations

This commit introduces new static factory methods in the Wavelength and Concentration classes, allowing for the creation of instances from nanometers and molar concentration values, respectively. These additions improve usability and support for unit conversions across various domains.
…micrometers, nanometers, and various vector dimensions

This commit enhances the DoubleExtensions and FloatExtensions classes by introducing new static factory methods for creating Length instances from micrometers and nanometers. Additionally, it adds methods for creating Position, Displacement, Velocity, and Force instances in both 2D and 3D from System.Numerics vectors. These improvements enhance usability and support for unit conversions across various dimensions.
This commit introduces several updates, including the addition of the ktsu.CodeBlocker package for improved code generation, updates to the Directory.Packages.props file to include new package versions, and the implementation of new source generation targets in the Semantics project. Additionally, it adds a new Generated directory for unit definitions and refines the project structure for better organization and maintainability.
This commit updates the Directory.Packages.props and global.json files to streamline package version management and SDK references. It removes outdated package versions, adds new SDK versions, and introduces a new GitHub Actions workflow for automatic SDK updates. Additionally, it refines the dotnet.yml workflow to support manual triggers and improve release conditions, enhancing overall project maintainability and build efficiency.
…tions

- Changed target frameworks to net10.0, net9.0, and net8.0.
- Added new package references for SourceLink and Polyfill.
- Removed unnecessary properties and targets related to generated files.
- Included InternalsVisibleTo for ktsu.Semantics.Test.
…text validation

- Deleted attributes for path validation: IsExtensionAttribute, IsFileNameAttribute, IsFilePathAttribute, IsPathAttribute, IsRelativePathAttribute, IsValidFileNameAttribute, IsValidPathAttribute.
- Removed text validation attributes: ContainsAttribute, EndsWithAttribute, IsBase64Attribute, IsEmailAddressAttribute, PrefixAndSuffixAttribute, RegexMatchAttribute, StartsWithAttribute.
- Eliminated the FluentValidationAdapter class and its base validation attribute class.
- Updated README to reflect the removal of obsolete attributes and provide clearer organization of validation components.
…dling

- Added Microsoft.Bcl.AsyncInterfaces version 9.0.3 to Directory.Packages.props.
- Refactored path validation and handling in AbsoluteDirectoryPath, AbsoluteFilePath, DirectoryPath, and RelativeDirectoryPath classes to use Ensure.NotNull instead of ArgumentNullException.
- Introduced PathHelper class for path-related utility methods to support netstandard2.0.
- Updated validation attributes to utilize PathHelper for path checks.
- Removed unnecessary using directives for ktsu.Semantics.Strings in various files.
- Updated tests to reflect changes in path handling and validation.
claude and others added 27 commits June 12, 2026 09:31
…from main

New generated dimensions: Permittivity (F/m), ElectricConductivity (S/m),
ElectricFlux (V·m, with ElectricField x Area relationship),
ElectricPowerDensity (W/m³, with x Volume => Power), Sensitivity (V/Pa,
with x Pressure => Voltage), ThermalResistance (K/W), RateConstant (s⁻¹),
Luminance (cd/m², Nit, FootLambert, with x Area => LuminousIntensity),
and the psychoacoustic Loudness (sone) and Sharpness (acum).

New semantic overloads: Impedance on Resistance (mirrors Admittance on
Conductance), SoundPressure on Pressure, SoundPower on Power,
SoundAbsorption / NoiseReductionCoefficient / SoundTransmissionClass on
Ratio, and the signed ReflectionCoefficient on SignedRatio.

Also fixes two latent metadata bugs:
- Luminance was modelled as an overload of Illuminance; lux (light
  arriving) and cd/m² (light leaving) are different quantities, so the
  overload is replaced by the proper Luminance dimension.
- The generator emits an identity factory for the first availableUnits
  entry, but Concentration listed Molar (x1000) and NuclearCrossSection
  listed Barn (x1e-28) first, so From{Base} and In(unit) disagreed about
  the storage unit. Both now lead with the true SI base unit
  (MolePerCubicMeter, SquareMeter); FromMolars and FromBarns now scale
  into SI storage as documented.

RateConstant deliberately has no Time integral: Frequency already owns
Ratio / Duration, and a second result type for the same operands cannot
compile.

https://claude.ai/code/session_01AUgbNJjDBDCwcbUfPK3pGW
Locks in the log-scale decision: decibel and pH scales don't obey linear
arithmetic, so they are self-contained record structs (like the
audio-engineering types) that convert to and from their linear generated
counterparts, not dimensions.json entries.

- SoundPressureLevel (dB re 20 µPa) <-> SoundPressure
- SoundIntensityLevel (dB re 1e-12 W/m²) <-> SoundIntensity
- SoundPowerLevel (dB re 1e-12 W) <-> SoundPower
- DirectionalityIndex (dB) <-> intensity Ratio
- PH <-> hydrogen-ion Concentration (plus pOH and acidity checks)

Documented as resolved design decision #5 in CLAUDE.md.

https://claude.ai/code/session_01AUgbNJjDBDCwcbUfPK3pGW
Backfill missing quantities + hand-written log-scale companions (SPL/SIL/SWL/DI/pH)
Covers the quantities namespace move, the vector-form type renames,
non-negative V0 semantics and absolute subtraction, the storage-unit
fixes (Concentration, NuclearCrossSection, Dalton), plural factories and
typed In(unit), the log-scale companion types, the PhysicalConstants
domain renames, and removed APIs with their replacements.

https://claude.ai/code/session_01AUgbNJjDBDCwcbUfPK3pGW
…branch

- Move Cents, Decibels, Gain, NormalizedParameter, ParameterTaper,
  Percent, QFactor and Semitones from ktsu.Semantics to
  ktsu.Semantics.Quantities, alongside every other quantity type.
- Delete the audio-specific Ratio<T>: the generated Dimensionless Ratio
  is the single ratio currency. Decibels.ToPower(), Cents/Semitones
  frequency-ratio conversions and Percent.FromRatio/ToRatio now exchange
  the generated type, and a Dimensionless x Dimensionless relationship
  supplies Ratio * Ratio (same-type division yields the storage value,
  as for every quantity).

https://claude.ai/code/session_01AUgbNJjDBDCwcbUfPK3pGW
Align audio-engineering types with vectors conventions
…hmic.json

Logarithmic quantities (decibel levels, pitch intervals, pH) now have a
metadata source of truth. Each logarithmic.json entry generates a
standalone readonly partial record struct built around
scale = multiplier · log_base(linear / reference): the raw-scalar
factory, From{Linear}/To{Linear} conversions against the linear
generated counterpart (with optional name overrides and a
PhysicalConstants- or literal-backed reference), optional log-space
+/- arithmetic, comparisons, and culture-invariant ToString.

Bespoke members that don't fit the schema (named constants,
cross-scale conversions, raw-T conveniences) live in hand-written
partials — QuantitiesGenerator now emits partial records throughout so
generated quantities can carry such companions too.

SEM005 flags missing/duplicate scale names and conversions with no
linear type.

https://claude.ai/code/session_01AUgbNJjDBDCwcbUfPK3pGW
- SoundPressureLevel, SoundIntensityLevel, SoundPowerLevel: fully
  generated from logarithmic.json; hand-written files deleted.
- Decibels, Cents, Semitones, DirectionalityIndex, PH: cores generated;
  the hand-written files shrink to bespoke partials (Unity, Unison,
  Octave, Omnidirectional, Neutral/ToPOH/IsAcidic/IsBasic, raw-T
  FromAmplitude/FromPower, Cents<->Semitones).
- Percent: was a standalone struct; now a unit of the Dimensionless
  dimension — Ratio.FromPercent(50) == 0.5, ratio.In(Units.Percent).
- Gain: was a standalone struct; now a generated semantic overload of
  Ratio (non-negative V0, widens implicitly), with Unity/Silence, the
  Decibels conversions, and cascading * kept in a partial.
- Decibels gains FromPowerRatio(Ratio<T>) alongside the raw-T
  conveniences; FromGain/ToAmplitude/ToPower are now generated.

Generated snapshots refreshed (all quantity records are now partial).

https://claude.ai/code/session_01AUgbNJjDBDCwcbUfPK3pGW
Updates resolved decision #5 in CLAUDE.md (logarithmic.json + partials,
SEM005), adds the 'adding a logarithmic scale' walk-through to
physics-generator.md, and refreshes the migration guide rows for
Percent (now a Dimensionless unit) and Gain (now a Ratio overload).

https://claude.ai/code/session_01AUgbNJjDBDCwcbUfPK3pGW
Metadata-generate the logarithmic scales; fold Percent/Gain into the linear metadata
Factory names are now the unit's singular lemma, emitted mechanically as
From{name} from the units.json `name` field. The generator no longer
encodes any English pluralisation:

- Remove the `factoryName` field (UnitsMetadata.FactoryName) and the
  `name + "s"` pluralisation fallback in QuantitiesGenerator; the factory
  suffix is simply the unit name verbatim.
- Singularise every compound unit name including its leading noun, so the
  rule stays mechanical: MetersPerSecond -> MeterPerSecond,
  KilometersPerHour -> KilometerPerHour, FeetPerSecond -> FootPerSecond,
  RadiansPerSecond -> RadianPerSecond, RevolutionsPerMinute ->
  RevolutionPerMinute, PartsPerMillion -> PartPerMillion (and the
  -Squared/-Cubed/-Quartic variants). This cascades to the generated unit
  type, singleton, and Name string, plus dimensions.json availableUnits and
  the matching conversions.json conversion-constant names.

Single-word factories therefore lose their plural too (FromMeters ->
FromMeter, FromKilograms -> FromKilogram, FromFeet -> FromFoot).

Regenerates committed generator output and updates tests and docs.

https://claude.ai/code/session_01VHVRpExJ2g51MeKjoRQTav
Singular-lemma factory names; drop factoryName pluralization
# Conflicts:
#	Directory.Packages.props
#	Semantics.Strings/SemanticString.cs
#	Semantics.Strings/Semantics.Strings.csproj
Add explicit accessibility modifiers to IUnit/IPhysicalQuantity members
(IDE0040), document UnitConversionException constructors (CS1591), remove
the duplicate <typeparam> across generated and hand-written partials so the
logarithmic types document T once (CS1710), and dedupe using directives in
the test project introduced by the main merge (CS0105/IDE0005).
Sync main into vectors and fix .NET 10 build
#50/#52 were already implemented in the generator (V0 factories guard via
Vector0Guards.EnsureNonNegative; V0 - V0 returns T.Abs(left - right)) but the
covering tests were left [Ignore]d. Un-skip and rename them.

Drop net5.0/net6.0/net7.0: System.Text.Json 10 and friends no longer ship
assets for those runtimes (they are out of support). Strings/Paths keep
netstandard2.0/2.1 so older consumers still resolve; Quantities goes to net8.0
floor (it needs INumber<T>). Document the TFM change in the 2.0 migration guide.
The committed Units.g.cs predated the catalogue's ordinal sort, so every build
re-ordered one singleton (FootPerSecond) and showed the file dirty. The
generator is deterministic (verified: two clean builds are byte-identical), so
this is a one-time resync.

Add a standalone verify-generated workflow that rebuilds and fails if anything
under Semantics.Quantities/Generated/ drifts from its generator. Kept separate
from the centrally-synced dotnet.yml.
Close V0 release blockers (#50, #52) and drop out-of-support TFMs
Add satellite packages ktsu.Semantics.Quantities.{Double,Float,Decimal}. Each
ships a buildTransitive props file that injects global-using aliases (e.g.
'global using Mass = ktsu.Semantics.Quantities.Mass<double>;') for all 220
quantity types, so a referencing project writes 'Mass' instead of 'Mass<double>'
with full type identity. Reference one package per project to pick the storage type.

The alias lists are generated from the quantity catalogue by
scripts/Generate-AliasProps.ps1 and committed; verify-generated CI now
regenerates and fails on drift.
…lias packages

- README: 7-badge format, drop net7 from targets, rebrand the Physics
  Quantities pillar to Semantic Quantities, add a Storage-type alias packages
  section, fix dimension/type counts.
- DESCRIPTION/TAGS: rebrand quantities as semantic quantities, drop the removed
  bootstrap-architecture claim, add source-generator and alias tags.
- CLAUDE.md: correct target frameworks, add the alias-package projects and the
  Generate-AliasProps regeneration step.
- docs/: rebrand the quantity category to 'semantic quantities' throughout
  (keeping genuine physics terms, file names, and PhysicalConstants), fix the
  stale net7 target line and a broken intra-doc anchor in architecture.md.
Breaking release. See docs/migration-guide-2.0.md for the 1.x -> 2.0 upgrade path:
renamed quantity types, namespace moves, generator-driven architecture, dropped
out-of-support TFMs, and the new storage-type alias packages.
@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
3 Security Hotspots
9.2% Coverage on New Code (required ≥ 80%)
D Reliability Rating on New Code (required ≥ A)
C Security Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

@matt-edmondson matt-edmondson merged commit 0bc1265 into main Jun 27, 2026
5 of 6 checks passed
@matt-edmondson matt-edmondson deleted the vectors branch June 27, 2026 09:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Reconcile IPhysicalQuantity / PhysicalQuantity surface with strategy doc and CLAUDE.md

2 participants