From 00ac9c3804a230e910677738b84e08478a21bf03 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 12 May 2026 14:02:29 +0000 Subject: [PATCH] docs(architecture): document physics generator pipeline (closes #61) Extend docs/architecture.md beyond strings/paths to cover the metadata-driven physics quantities subsystem: source-of-truth files, generator pipeline diagram, vector-form invariants, and SEM001-SEM004 diagnostics. Add SEM004 to the README diagnostic list. https://claude.ai/code/session_01LqtywMUn5GwFATD5FDdLn6 --- README.md | 1 + docs/architecture.md | 62 ++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 588a93d..27c950d 100644 --- a/README.md +++ b/README.md @@ -181,6 +181,7 @@ Generator diagnostics catch metadata problems at build time: - **SEM001** — relationship references an unknown dimension name. - **SEM002** — schema-level metadata issue (missing fields, duplicate type names, etc). - **SEM003** — relationship's `forms` list references a vector form not declared on a participating dimension. +- **SEM004** — `availableUnits` references a unit not declared in `units.json`. Generated output is committed to `Semantics.Quantities/Generated/` so the project compiles without first running the generator. diff --git a/docs/architecture.md b/docs/architecture.md index f09f0c7..f464fda 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -1,6 +1,10 @@ # Architecture Guide -This document provides a detailed overview of the Semantics library architecture, focusing on the SOLID principles and DRY practices implemented throughout the codebase. +This document covers the architecture of the **semantic strings, paths, and validation** subsystems. The physics quantities subsystem is metadata-driven and is documented separately: + +- [`docs/strategy-unified-vector-quantities.md`](strategy-unified-vector-quantities.md) — the unified `IVector0..IVector4` model. +- [`docs/physics-generator.md`](physics-generator.md) — `dimensions.json` schema and the source-generator pipeline. +- The [Physics Quantities: Metadata-Driven Generation](#physics-quantities-metadata-driven-generation) section below provides a short orientation and links into those documents. ## Table of Contents @@ -10,11 +14,12 @@ This document provides a detailed overview of the Semantics library architecture - [Design Patterns](#design-patterns) - [Class Hierarchy](#class-hierarchy) - [Validation System](#validation-system) +- [Physics Quantities: Metadata-Driven Generation](#physics-quantities-metadata-driven-generation) - [Testing Strategy](#testing-strategy) ## Overview -The Semantics library is designed around clean architecture principles, with a focus on maintainability, extensibility, and testability. The core philosophy is to provide type-safe string wrappers while maintaining excellent separation of concerns and avoiding code duplication. +The Semantics library is built around three pillars — **semantic strings**, **semantic paths**, and **physics quantities** — sharing a single philosophy: replace primitive obsession with strongly-typed, self-validating domain models. Strings and paths use a hand-authored attribute → strategy → rule → factory pipeline (described in this document). Physics quantities are emitted at compile time by a Roslyn incremental generator from declarative metadata (described in [Physics Quantities: Metadata-Driven Generation](#physics-quantities-metadata-driven-generation)). All three subsystems target `net10.0`, `net9.0`, `net8.0`, `net7.0`. ## SOLID Principles Implementation @@ -271,6 +276,59 @@ User Creates Semantic String Return Valid Object or Throw Exception ``` +## Physics Quantities: Metadata-Driven Generation + +Unlike strings and paths — which are hand-authored — every physics quantity type, factory, operator, and constant is emitted by a Roslyn incremental generator. The single source of truth is `Semantics.SourceGenerators/Metadata/`: + +| File | Contents | +|---|---| +| `dimensions.json` | Every physical dimension, the vector forms it supports (`Vector0`..`Vector4`), its `availableUnits`, semantic overloads (e.g. `Weight` over `ForceMagnitude`), and cross-dimensional relationships (`integrals`, `derivatives`, `dotProducts`, `crossProducts`). | +| `units.json` | Unit declarations with `factoryName` (plural) and a base-unit conversion expression. | +| `magnitudes.json` | SI magnitude prefixes for unit derivations. | +| `conversions.json` | Conversion factors between non-SI units and the SI base. | +| `domains.json` | Domain grouping for `PhysicalConstants` (e.g. `Fundamental`, `Chemistry`, `AngularMechanics`). | + +### Generator pipeline + +``` +Metadata/*.json + │ + ▼ +Semantics.SourceGenerators (Roslyn IIncrementalGenerator) + │ + ├── QuantitiesGenerator → one record per quantity (V0/V1/V2/V3/V4 + overloads) + │ + From{Unit} factory per declared unit + │ + Vector0Guards.EnsureNonNegative / EnsurePositive + │ + cross-dimensional *, /, Dot, Cross operators + ├── ConversionsGenerator → unit-to-SI conversion helpers + ├── PhysicalConstantsGenerator → PhysicalConstants..* (PreciseNumber) + │ + PhysicalConstants.Generic.*() (T.CreateChecked) + └── StorageHelpersGenerator → DivideToStorage with DivideByZeroException + │ + ▼ +Semantics.Quantities/Generated/ (committed source — diff before commit) +``` + +### Vector-form invariants + +These are enforced structurally by the generated types and locked in by `Semantics.Test`: + +1. `V0` magnitudes are non-negative; the SI factory throws `ArgumentException` on a negative value, and `V0 - V0` returns `T.Abs(a - b)` to preserve the invariant. +2. A V0 overload can opt into a strict-positive guard with `physicalConstraints: { "minExclusive": "0" }` (used by `Wavelength`, `Period`, `HalfLife`); `EnsurePositive` then rejects zero as well. +3. Semantic overloads widen implicitly to their base, narrow explicitly (`Weight.From(forceMagnitude)`). +4. `IVectorN.Magnitude()` for N ≥ 1 returns the corresponding `IVector0`. + +### Generator diagnostics + +Metadata errors fail the build rather than silently emitting wrong code: + +- **SEM001** — a relationship references a dimension that does not exist. +- **SEM002** — schema-level metadata issue (missing `name` / `symbol`, empty `availableUnits`, duplicate type names, no vector forms declared). +- **SEM003** — a relationship's explicit `forms` list references a vector form not declared on a participating dimension. +- **SEM004** — a dimension's `availableUnits` array references a unit name that isn't declared in `units.json` (catches typos that would otherwise produce a wrong identity-conversion factory). + +For the schema, an end-to-end "add a dimension" walk-through, and the design rationale, see [`docs/physics-generator.md`](physics-generator.md) and [`docs/strategy-unified-vector-quantities.md`](strategy-unified-vector-quantities.md). + ## Testing Strategy ### Contract Testing