Vector0 quantities do not enforce the non-negativity invariant #50
Description
Summary
docs/strategy-unified-vector-quantities.md defines IVector0<TSelf, T> as a magnitude-only quantity that "enforces non-negativity as a type-level invariant", citing examples like:
Speed<double> s = Speed.FromMetersPerSecond(-1.0); // throws: magnitude cannot be negativeIn practice, no enforcement exists. Generated Vector0 quantities (Speed, Mass, Distance, Energy, Area, …) accept any value, including negatives.
Evidence
Semantics.Quantities/Generated/.../Mass.g.cs:
public static Mass<T> FromKilogram(T value) => Create(value);No guard. grep -E "cannot be negative|ArgumentOutOfRange|absolute zero" Generated/.../{Speed,Mass,Temperature}.g.cs returns nothing.
Semantics.Quantities/PhysicalQuantity.cs also does not validate; it is a thin wrapper exposing Value.
Suggested next step
Decide where the constraint lives:
- Emit a guard inside the
Create/From*factories of any quantity declared asVector0indimensions.json, throwingArgumentException(per CLAUDE.md's validation guidance) whenT.Sign(value) < 0. - Or move the guard into a shared helper on
PhysicalQuantity<T>/ aVector0<T>base.
Either way, add tests in Semantics.Test that assert negative-input rejection across every Vector0 quantity.
Area / Severity
SourceGenerators / Quantities · incomplete
Activity
Merge pull request #68 from ktsu-dev/work/issue-50-52
matt-edmondson commentedon May 9, 2026
Resolved by #68 (commit 039afc4).
Vector0Guards.EnsureNonNegativeis invoked from every generatedFrom{Unit}factory on V0 base types and V0 semantic overloads, throwingArgumentExceptionfor negative inputs. Coverage is inSemantics.Test/Quantities/Vector0InvariantTests.cs(Speed, Mass, Length, Energy, Distance, Weight, plus float/decimal storage variants). The committedGenerated/tree was stale relative to that work and is being refreshed in #70.Generated by Claude Code
Merge pull request #101 from ktsu-dev/fix/vectors-release-blockers
test: cover IVector*/Magnitude/Dot/Cross and overload conversions
feat(quantities): enforce V0 non-negativity and absolute V0-V0 subtra…
feat(generator): add SEM002 metadata validation; refresh stale genera…
feat(generator): plural From{Unit} factory naming + form matrix docs (c…
feat(quantities): per-overload physicalConstraints + EnsurePositive g…
docs: fix stale README + guides — plural factories, V3 object-init, r…
fix: close V0 release blockers and drop out-of-support TFMs