|
1 | 1 | # CLAUDE.md |
2 | 2 |
|
3 | | -This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 3 | +Guidance for Claude Code working in this repository. Read this together with `docs/strategy-unified-vector-quantities.md` (the architecture spec for the physics system) and `docs/physics-generator.md` (the metadata workflow). |
4 | 4 |
|
5 | | -## Build Commands |
| 5 | +## Build commands |
6 | 6 |
|
7 | | -This is a .NET C# library project that uses custom MSBuild SDKs from ktsu. Common development commands: |
| 7 | +This is a multi-target .NET library (`net10.0;net9.0;net8.0;net7.0`) using ktsu MSBuild SDKs. |
8 | 8 |
|
9 | 9 | - **Build**: `dotnet build` |
10 | | -- **Test**: `dotnet test` (runs all unit tests with coverage) |
11 | | -- **Test (no parallel)**: `dotnet test --logger "console;verbosity=detailed"` |
| 10 | +- **Test**: `dotnet test` |
| 11 | +- **Test (verbose)**: `dotnet test --logger "console;verbosity=detailed"` |
12 | 12 | - **Clean**: `dotnet clean` |
13 | 13 | - **Restore**: `dotnet restore` |
14 | | -- **Format**: `dotnet format` (fixes formatting issues like IDE0055) |
| 14 | +- **Format**: `dotnet format` |
15 | 15 |
|
16 | | -The project uses MSTest for unit testing with comprehensive coverage across all physics domains. |
| 16 | +Tests use MSTest. Generator output is emitted to `Semantics.Quantities/Generated/` (committed) so the project can be inspected without first running the generator. |
17 | 17 |
|
18 | | -## Project Architecture |
| 18 | +## Project layout |
19 | 19 |
|
20 | | -### Core Components |
| 20 | +| Project | Responsibility | |
| 21 | +|---|---| |
| 22 | +| `Semantics.Strings` | Strongly-typed string wrappers (`SemanticString<T>`) and validation attributes/strategies. | |
| 23 | +| `Semantics.Paths` | Polymorphic file system path types (`IPath`, `IFilePath`, `IDirectoryPath`, …). | |
| 24 | +| `Semantics.Quantities` | Hand-written runtime types (`PhysicalQuantity<TSelf, T>`, `IVector0`..`IVector4`, `UnitSystem`) plus generator output under `Generated/`. | |
| 25 | +| `Semantics.SourceGenerators` | Roslyn incremental generators that emit quantity types, units, conversions, magnitudes, physical constants, and storage-type helpers from metadata. | |
| 26 | +| `Semantics.Test` | MSTest project covering all of the above. | |
21 | 27 |
|
22 | | -**ktsu.Semantics** is a comprehensive .NET library for creating type-safe, validated types with semantic meaning, encompassing three major areas: |
| 28 | +## Physics quantities architecture (the unified vector model) |
23 | 29 |
|
24 | | -1. **Semantic Strings** - Strongly-typed string wrappers with validation |
25 | | -2. **Semantic Paths** - Specialized file system path handling with polymorphic interfaces |
26 | | -3. **Physics Quantities System** - Complete physics quantities across 8 scientific domains |
| 30 | +The physics system is **metadata-driven**. The single source of truth is |
| 31 | +`Semantics.SourceGenerators/Metadata/dimensions.json`, which lists every physical dimension and the vector forms it supports. |
27 | 32 |
|
28 | | -### Key Architectural Patterns |
| 33 | +Every quantity is a vector. Dimensionality of the *direction space* is part of the type: |
29 | 34 |
|
30 | | -- **Bootstrap Architecture**: Resolves circular dependencies between units, dimensions, and constants using `BootstrapUnits` class |
31 | | -- **Generic Type Safety**: All physics quantities use generic constraints `where T : struct, INumber<T>` |
32 | | -- **Factory Pattern**: `SemanticStringFactory<T>` for dependency injection scenarios |
33 | | -- **Polymorphic Path Interfaces**: Rich interface hierarchy (`IPath`, `IFilePath`, `IDirectoryPath`, etc.) |
| 35 | +| Form | Meaning | Sign | Examples | |
| 36 | +|---|---|---|---| |
| 37 | +| `IVector0<TSelf, T>` | Magnitude only | Always `>= 0` | `Speed`, `Mass`, `Energy`, `Distance`, `Area` | |
| 38 | +| `IVector1<TSelf, T>` | Signed 1D | Signed | `Velocity1D`, `Force1D`, `Temperature`, `ElectricCharge` | |
| 39 | +| `IVector2<TSelf, T>` | 2D directional | Per-component | `Velocity2D`, `Force2D`, `Acceleration2D` | |
| 40 | +| `IVector3<TSelf, T>` | 3D directional | Per-component | `Velocity3D`, `Force3D`, `Position3D` | |
| 41 | +| `IVector4<TSelf, T>` | 4D directional | Per-component | (reserved for relativistic / spacetime) | |
34 | 42 |
|
35 | | -### Physics System Structure |
| 43 | +`IVectorN.Magnitude()` (for N >= 1) returns the corresponding `IVector0`. |
36 | 44 |
|
37 | | -**8 Complete Domains** (80+ quantities total): |
38 | | -- Mechanics (15): Force, Energy, Power, Pressure, Velocity, etc. |
39 | | -- Electrical (11): Voltage, Current, Resistance, Capacitance, etc. |
40 | | -- Thermal (10): Temperature, Heat, Entropy, Thermal Conductivity, etc. |
41 | | -- Chemical (10): AmountOfSubstance, Concentration, pH, Reaction rates, etc. |
42 | | -- Acoustic (20): Frequency, Sound pressure/power, Wavelength, etc. |
43 | | -- Nuclear (5): Radioactive activity, Absorbed dose, Exposure, etc. |
44 | | -- Optical (6): Luminous flux, Illuminance, Refractive index, etc. |
45 | | -- Fluid Dynamics (5): Viscosity, Flow rates, Reynolds number, etc. |
| 45 | +All generated types are generic over a numeric storage type: `where T : struct, INumber<T>`. |
46 | 46 |
|
47 | | -### Physical Constants System |
| 47 | +### Resolved design decisions |
48 | 48 |
|
49 | | -Centralized in `PhysicalConstants` class with type-safe generic access: |
50 | | -- `PhysicalConstants.Generic.SpeedOfLight<T>()` |
51 | | -- `PhysicalConstants.Generic.PlanckConstant<T>()` |
52 | | -- `PhysicalConstants.Conversion.FeetToMeters<T>()` |
| 49 | +These are now baked into the generator and enforced by tests. **Do not reopen without an architecture discussion.** |
53 | 50 |
|
54 | | -All derived constants are validated against fundamental relationships in comprehensive unit tests. |
| 51 | +1. **`V0 - V0` returns the same `V0` of `T.Abs(a - b)`.** Magnitude subtraction stays non-negative; signed subtraction must use the V1 form explicitly. |
| 52 | +2. **Dimensionless and angular quantities have both `Ratio` (V0) and `SignedRatio` (V1) bases.** Ratios that semantically must be non-negative (e.g. `RefractiveIndex`, `MachNumber`, `SpecificGravity`) are V0 overloads of `Ratio`. |
| 53 | +3. **Semantic overloads widen implicitly to their base, narrow explicitly from it.** A `Weight` is implicitly a `ForceMagnitude`; the reverse requires `Weight.From(forceMagnitude)` or an explicit cast. |
| 54 | +4. **Physical constraints come from per-dimension metadata.** Floors like absolute zero or non-negative frequency are declared in `dimensions.json` and the generator emits `ArgumentException`-throwing guards inside the `Create`/`From*` factories. |
55 | 55 |
|
56 | | -## Code Standards and Guidelines |
| 56 | +### Physical constants |
| 57 | + |
| 58 | +`PhysicalConstants` is **generated** from `dimensions.json` (and a constants fixture). Public surface: |
| 59 | + |
| 60 | +```csharp |
| 61 | +PhysicalConstants.Generic.SpeedOfLight<T>() |
| 62 | +PhysicalConstants.Generic.PlanckConstant<T>() |
| 63 | +PhysicalConstants.Conversion.FeetToMeters<T>() |
| 64 | +``` |
| 65 | + |
| 66 | +Use these accessors instead of hard-coded numerics. Backing values are stored as `PreciseNumber` and converted with `T.CreateChecked` per call. |
| 67 | + |
| 68 | +### Operators and physics relationships |
| 69 | + |
| 70 | +Cross-dimensional relationships are also declared in `dimensions.json` (`integrals`, `derivatives`, `dotProducts`, `crossProducts`). The generator emits operators like: |
| 71 | + |
| 72 | +```csharp |
| 73 | +public static Energy<T> operator *(Force1D<T> f, Length<T> d) => |
| 74 | + Energy<T>.Create(f.Value * d.Value); |
| 75 | +``` |
| 76 | + |
| 77 | +All values are stored in SI base units, so operators read `.Value` directly. Suppress `CA2225` on physics operators because "named alternates" (`Add`, `Multiply`) don't carry the dimensional meaning: |
57 | 78 |
|
58 | | -### File Headers |
59 | | -Always include this header on new files: |
60 | 79 | ```csharp |
61 | | -// Copyright (c) KTSU. All rights reserved. |
| 80 | +[System.Diagnostics.CodeAnalysis.SuppressMessage( |
| 81 | + "Usage", "CA2225:Operator overloads have named alternates", |
| 82 | + Justification = "Physics relationship operators represent fundamental equations.")] |
62 | 83 | ``` |
63 | 84 |
|
64 | | -### Physics Quantities Standards |
65 | | -- Use `PhysicalConstants.Generic` methods instead of hardcoded values |
66 | | -- Implement physics relationships as operators with dimensional analysis |
67 | | -- Suppress CA2225 warnings for physics operators: |
| 85 | +## Code standards |
| 86 | + |
| 87 | +### File headers |
| 88 | + |
68 | 89 | ```csharp |
69 | | -[System.Diagnostics.CodeAnalysis.SuppressMessage("Major Code Smell", "CA2225:Provide named alternates for operator overloads", Justification = "Physics relationship operators represent fundamental equations, not arithmetic")] |
| 90 | +// Copyright (c) ktsu.dev |
| 91 | +// All rights reserved. |
| 92 | +// Licensed under the MIT license. |
70 | 93 | ``` |
71 | 94 |
|
72 | | -### Validation and Error Handling |
73 | | -- Throw `ArgumentException` for validation failures (not `FormatException`) |
74 | | -- Use specific exception types instead of general exceptions |
75 | | -- Temperature values cannot be below absolute zero (0 K) |
76 | | -- Frequency values cannot be negative |
77 | | -- Throw `DivideByZeroException` when dividing by zero in `DivideToStorage` |
| 95 | +Generator-emitted files additionally carry `// <auto-generated />`. |
| 96 | + |
| 97 | +### Validation and error handling |
| 98 | + |
| 99 | +- Throw `ArgumentException` for validation failures (not `FormatException`). |
| 100 | +- Throw `DivideByZeroException` when dividing by zero in `DivideToStorage`. |
| 101 | +- Use the most specific exception type available. |
| 102 | + |
| 103 | +### Testing |
| 104 | + |
| 105 | +- Use explicit types (no `var`) in test bodies. |
| 106 | +- Pre-create fixtures outside measurement loops in performance tests. |
| 107 | +- Mark OS-specific tests with `[TestCategory("OS-Specific")]`. |
| 108 | +- Use 259-character path limit for cross-platform path tests. |
| 109 | +- Force GC before memory measurements: `GC.Collect(); GC.WaitForPendingFinalizers();` |
78 | 110 |
|
79 | | -### Testing Standards |
80 | | -- Use explicit types instead of `var` |
81 | | -- Pre-create objects outside measurement loops in performance tests |
82 | | -- Mark OS-specific tests with `[TestCategory("OS-Specific")]` |
83 | | -- Use path length limit of 259 characters for cross-platform compatibility |
84 | | -- Force GC before memory measurements: `GC.Collect(); GC.WaitForPendingFinalizers()` |
| 111 | +### XML documentation |
85 | 112 |
|
86 | | -### XML Documentation Standards |
87 | | -- Use explicit dimension documentation: `/// <summary>Gets the physical dimension of [quantity] [SYMBOL].</summary>` |
88 | | -- Constructor documentation: `/// <summary>Initializes a new instance of the <see cref="[ClassName]{T}"/> class.</summary>` |
89 | | -- Include `<param>`, `<returns>`, `<exception>`, and `<see cref="">` tags appropriately |
| 113 | +- `/// <summary>Gets the physical dimension of <quantity> [<symbol>].</summary>` style for dimension properties. |
| 114 | +- Include `<param>`, `<returns>`, `<exception>`, and `<see cref="">` tags on public APIs. |
90 | 115 |
|
91 | | -## Important Implementation Notes |
| 116 | +## Important implementation notes |
| 117 | + |
| 118 | +### Semantic string creation |
92 | 119 |
|
93 | | -### Semantic String Creation |
94 | 120 | ```csharp |
95 | | -// Preferred creation methods |
96 | 121 | var email = EmailAddress.Create("user@example.com"); |
97 | 122 | var userId = UserId.Create("USER_123"); |
98 | 123 |
|
99 | 124 | // Extension method conversion |
100 | | -var email = "user@example.com".As<EmailAddress>(); |
| 125 | +var email2 = "user@example.com".As<EmailAddress>(); |
101 | 126 |
|
102 | 127 | // Cross-type conversion |
103 | 128 | var converted = sourceString.As<SourceType, TargetType>(); |
104 | 129 | ``` |
105 | 130 |
|
106 | | -### Path Interface Usage |
107 | | -Complete conversion API: |
108 | | -- `AsAbsolute()` - Convert to absolute using current working directory |
109 | | -- `AsAbsolute(baseDirectory)` - Convert to absolute using specific base |
110 | | -- `AsRelative(baseDirectory)` - Convert to relative using specific base |
| 131 | +### Path conversion |
111 | 132 |
|
112 | | -### Physics Relationships Implementation |
113 | | -Use `.Value` property directly for calculations since quantities are already in SI base units: |
114 | | -```csharp |
115 | | -// Force * Length = Energy (Work) |
116 | | -public static Energy<T> operator *(Force<T> force, Length<T> length) => |
117 | | - Energy<T>.FromJoules(force.Value * length.Value); |
118 | | -``` |
| 133 | +- `AsAbsolute()` — convert to absolute using current working directory. |
| 134 | +- `AsAbsolute(baseDirectory)` — convert to absolute using a specific base. |
| 135 | +- `AsRelative(baseDirectory)` — convert to relative against a specific base. |
| 136 | + |
| 137 | +### Working with the source generator |
| 138 | + |
| 139 | +- Edit `Semantics.SourceGenerators/Metadata/dimensions.json` to add a dimension, vector form, semantic overload, or relationship. |
| 140 | +- Rebuild `Semantics.SourceGenerators` and the consuming `Semantics.Quantities` project; emitted files appear in `Semantics.Quantities/Generated/Semantics.SourceGenerators/<GeneratorName>/`. |
| 141 | +- Treat generator output as committed source. Diff it before commit so accidental regressions are visible. |
| 142 | +- See `docs/physics-generator.md` for the full schema and an end-to-end "add a dimension" walk-through. |
119 | 143 |
|
120 | | -### Bootstrap vs Regular Units |
121 | | -- Use `BootstrapUnits` in `PhysicalDimensions.cs` to avoid circular dependencies |
122 | | -- Replace with full `Units` class after system initialization |
123 | | -- Keep bootstrap units in dedicated `BootstrapUnits` class |
| 144 | +This file is the entry point. For deeper material: |
124 | 145 |
|
125 | | -This architecture enables a sophisticated type-safe physics system while maintaining clean separation of concerns and avoiding circular dependencies through the bootstrap pattern. |
| 146 | +- `docs/strategy-unified-vector-quantities.md` — architecture spec for the unified vector model. |
| 147 | +- `docs/physics-generator.md` — generator + `dimensions.json` schema. |
| 148 | +- `docs/architecture.md` — semantic strings/paths/validation architecture (SOLID, design patterns). |
| 149 | +- `docs/complete-library-guide.md` — user-facing guide to all components. |
| 150 | +- `docs/validation-reference.md` — list of validation attributes. |
| 151 | +- `docs/advanced-usage.md` — advanced patterns for strings/paths. |
0 commit comments