You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
The C++ and .NET generators read physicalConstraints by different rules, so the next constraint added will fork the two APIs #218
MetadataConstraints.MinExclusive defaults to string.Empty (Semantics.Cpp/QuantityMetadata.cs:130), so a non-null constraints object with no minExclusive — or with any value other than "0" — lands on opposite answers.
Failure scenario
Add "physicalConstraints": {}, or {"minExclusive": "1"}, to any V0 overload.
C++ emits the strict guard (Semantics.Cpp/CppQuantityGenerator.cs:239-244):
The same declared quantity now has two different domains depending on which language you generate.
Why it matters
Today's three constraint sites — Wavelength, Period, HalfLife, all {"minExclusive": "0"} — agree by coincidence. So nothing is broken right now, and nothing would catch it breaking.
CLAUDE.md's design decision #4 is explicit that the strict rule is opted into by minExclusive: "0"specifically:
A V0 overload can opt into a stricter rule by declaring physicalConstraints: { "minExclusive": "0" } in dimensions.json (#51); the generator then emits Vector0Guards.EnsurePositive and rejects zero too.
The C++ side does not implement that rule — it implements "any constraints at all". The next constraint added to the metadata silently forks the two APIs, and the divergence surfaces as a C++ assertion failing on a value .NET accepts.
Suggested fix
Make QuantityVocabulary test PhysicalConstraints?.MinExclusive == "0", matching QuantitiesGenerator.
Better still, factor the predicate so both generators call one implementation — this is the second case in this repo (see the dimensional-check divergence) where one metadata file is read by two generators with no shared decision logic.
Add a Semantics.Cpp.Test case asserting the Magnitude chosen for an overload with a non-"0" constraint, so the two cannot drift again.
What needs to be done: The .NET generator tests physicalConstraints.MinExclusive == "0" exactly (the documented opt-in rule), while the C++ generator tests only whether physicalConstraints is non-null — so any future constraint that is present but isn't minExclusive: "0" (an empty object, or a different threshold) will make the two projections choose different runtime guards for the same declared quantity. No live bug today (the three existing constraint sites happen to agree by coincidence), but it's a landmine for the next metadata addition.
Suggested next steps / acceptance criteria:
Make QuantityVocabulary's Magnitude selection test PhysicalConstraints?.MinExclusive == "0", matching QuantitiesGenerator's rule exactly.
Add a Semantics.Cpp.Test case with a non-"0"physicalConstraints value (e.g. {} or minExclusive: "1"), asserting the chosen Magnitude matches what the .NET generator would choose.
Blockers / dependencies: None identified. Worth doing in the same pass as #216's part (b) if a shared cross-generator validation module is introduced, but not blocking either way.
Activity
matt-edmondson commentedon Sep 11, 2026
Triage
Priority: Medium Effort: Small
What needs to be done: The .NET generator tests
physicalConstraints.MinExclusive == "0"exactly (the documented opt-in rule), while the C++ generator tests only whetherphysicalConstraintsis non-null — so any future constraint that is present but isn'tminExclusive: "0"(an empty object, or a different threshold) will make the two projections choose different runtime guards for the same declared quantity. No live bug today (the three existing constraint sites happen to agree by coincidence), but it's a landmine for the next metadata addition.Suggested next steps / acceptance criteria:
QuantityVocabulary'sMagnitudeselection testPhysicalConstraints?.MinExclusive == "0", matchingQuantitiesGenerator's rule exactly.Semantics.Cpp.Testcase with a non-"0"physicalConstraintsvalue (e.g.{}orminExclusive: "1"), asserting the chosenMagnitudematches what the .NET generator would choose.Blockers / dependencies: None identified. Worth doing in the same pass as #216's part (b) if a shared cross-generator validation module is introduced, but not blocking either way.
Generated by Claude Code
State the strict-floor rule once, and pin it [patch]