What's wrong
SchemaDataValidator.ValidateValue (Schema/Models/SchemaDataValidator.cs L226-295) handles:
- primitives
- vectors
- colours
Enum, Object and Array
Every other type reaches default: break; (L292-293) and is never checked. That means Semantic, Quantity, Optional, Handle and Result values pass unchecked. These are the types samples/modernised.schema.json and CLAUDE.md now recommend ("Name the quantity, not the unit").
The vector cases have a gap of their own. They call ExpectNumericTuple (L460-483), which only checks that each component is a JSON number and ignores Vector.ElementType. So a Vector2<Int> accepts [1.5, 2.7].
Failure scenario (reproduced against 5ee8ed1)
Take a class Body with these members:
Id: Semantic(EntityId), where EntityId is over Long
Mass: Quantity(Mass)
Cell: Vector2 with elementType: Int
Maybe: Optional<Int>
This call returns 0 issues:
ValidateData(Body, "{ \"Id\": \"not a number\", \"Mass\": {\"x\":true}, \"Cell\": [1.5, 2.7], \"Maybe\": \"nope\" }", "data")
Suggested fix
- Semantic: validate the value against the semantic type's representation. Follow the refinement chain to the underlying type, the way
Represented in Schema.Validation.cs does. Skip chains that are unresolved or cyclic, because Validate() already reports those.
- Quantity: get the arity from
QuantityRegistry.TryResolve(...).Components.
- Arity 1: expect a number.
- Arity N: expect an array of N numbers.
- Check each value against
Storage, so Int and Long storage require integral values.
- Optional: accept
null. Otherwise validate the value against the element type.
- Vector: validate each component against
ElementType. Use ExpectIntegral for Int/Long, and check semantic components through their representation.
- Handle / Result / Interface / Span: these have no data-file form. Emit an explicit "cannot be checked" warning instead of accepting them silently, as
None already does.
Acceptance criteria
- The payload above yields one error each for
Id, Mass, Cell[0], Cell[1] and Maybe.
"Maybe": null yields no issues.
- A correct
Mass yields no issues: a number for a scalar quantity, or an array of the right arity for a vector one.
- Tests in
Schema.Test cover each type.
What's wrong
SchemaDataValidator.ValidateValue(Schema/Models/SchemaDataValidator.csL226-295) handles:Enum,ObjectandArrayEvery other type reaches
default: break;(L292-293) and is never checked. That meansSemantic,Quantity,Optional,HandleandResultvalues pass unchecked. These are the typessamples/modernised.schema.jsonand CLAUDE.md now recommend ("Name the quantity, not the unit").The vector cases have a gap of their own. They call
ExpectNumericTuple(L460-483), which only checks that each component is a JSON number and ignoresVector.ElementType. So aVector2<Int>accepts[1.5, 2.7].Failure scenario (reproduced against 5ee8ed1)
Take a class
Bodywith these members:Id: Semantic(EntityId), whereEntityIdis overLongMass: Quantity(Mass)Cell: Vector2withelementType: IntMaybe: Optional<Int>This call returns 0 issues:
Suggested fix
RepresentedinSchema.Validation.csdoes. Skip chains that are unresolved or cyclic, becauseValidate()already reports those.QuantityRegistry.TryResolve(...).Components.Storage, soIntandLongstorage require integral values.null. Otherwise validate the value against the element type.ElementType. UseExpectIntegralforInt/Long, and check semantic components through their representation.Nonealready does.Acceptance criteria
Id,Mass,Cell[0],Cell[1]andMaybe."Maybe": nullyields no issues.Massyields no issues: a number for a scalar quantity, or an array of the right arity for a vector one.Schema.Testcover each type.