Repository navigation
Sensitivity's dimensional formula matches neither V/Pa nor A/Pa, and the .NET generator emits the operator the C++ projection refuses #216
Description
Activity
matt-edmondson commented
on Sep 11, 2026 ContributorAuthorMore actionsTriage
Priority: High Effort: Medium
What needs to be done:
Sensitivity's declared dimensional formula matches neither its own unit (V/Pa) nor the A/Pa reading CLAUDE.md describes (which is itself internally inconsistent about the sign). The C++ projection catches this and refuses to emit theSensitivity × Pressure = ElectricPotentialoperator, but the .NET generator has no dimensional-consistency check at all, so it emits the operator into committed generated source — a type-checked but dimensionally false physics relationship that silently ships.Suggested next steps / acceptance criteria:
- (a) Physics decision + metadata fix: pick the correct formula for
Sensitivity— eitherV/Pawith{length: 3, time: -1, electricCurrent: -1}(matches the declared unit, makes the relationship true) orA/Pawith{mass: -1, length: 1, time: 2, electricCurrent: 1}(requires changing the unit too) — and correct thesymbolstring and CLAUDE.md's description to match. This step needs a maintainer/physics call before implementation, not just a code change. - (b) Port the exponent-consistency check from
Semantics.Cpp/DimensionVector.csinto the .NET generator as a newSEM00xdiagnostic, so this class of divergence is caught at generation time for every relationship, not just the ones that happen to reach the C++ projection.
Blockers / dependencies: Part (a) is blocked on a physics decision (which of the two formulas is correct) — flag for maintainer input. Part (b) is independent and can proceed without waiting on (a); it's the more durable fix since it prevents the next such error from being invisible on the .NET side.
Generated by Claude Code
- (a) Physics decision + metadata fix: pick the correct formula for
matt-edmondson commented
on Sep 21, 2026 ContributorAuthorMore actionsBoth halves of this have already landed on
mainI picked this up to implement part (b) — the triage note says it is unblocked and independent — and found that both (a) and (b) are already done. Verified against
mainatcf10208:(a) The metadata is fixed, and the
V/Pareading won.Semantics.SourceGenerators/Metadata/dimensions.jsonnow declares:"name": "Sensitivity", "symbol": "L³ T⁻¹ I⁻¹", "dimensionalFormula": { "length": 3, "time": -1, "electricCurrent": -1 }
That is exactly the first of the two options this issue proposed, and it matches the declared
VoltPerPascalunit. The relationship is now dimensionally true — working the exponents out from the current file:M L T I Sensitivity0 3 −1 −1 Pressure1 −1 −2 0 product 1 2 −3 −1 ElectricPotential1 2 −3 −1 The product and the declared result agree on every axis. So the emitted
Sensitivity<T> * Pressure<T> => VoltageMagnitude<T>operator is no longer the dimensionally false one described here — it is correct now, which is why it is still present in the committed generated source.(b) The exponent check is in the .NET generator, as
SEM008.AnalyzerReleases.Unshipped.mdregisters it as "Reports a relationship whose declared result does not follow from the dimensions of its operands, or whose signed value cannot land in a magnitude result." The arithmetic was not re-implemented —DimensionVectorandQuantityVocabularymoved into a sharedSemantics.Vocabularyproject, whichSemantics.SourceGenerators.csprojcompiles in as source (<Compile Include="..\Semantics.Vocabulary\*.cs" />), so the two projections now run the same check rather than only the C++ side having one. Emission is driven by the vocabulary, so no operator is generated for a refused relationship.The documentation was updated too, so there is no stale sign left to correct:
CLAUDE.md:146-150records the fix and theL³ T⁻¹ I⁻¹formula,Semantics.Vocabulary/README.md:13-14explains the SEM001/SEM003-only history, anddocs/migration-guide-5.0.md:124-125notes this relationship specifically.Nothing in the acceptance criteria is outstanding, so I am closing this as completed rather than opening a no-op PR. Please reopen if the physics call between
V/PaandA/Pawas meant to go the other way — that is the one thing I took as settled by the committed metadata rather than verified independently.
Generated by Claude Code
The metadata
Semantics.SourceGenerators/Metadata/dimensions.json:Its only unit is
VoltPerPascal, symbolV/Pa(units.json:890-893). Working the exponents out:The declared vector is neither. CLAUDE.md's own account ("declared as A/Pa,
M⁻¹L⁻¹T²I") is itself inconsistent — A/Pa haslength+1, not −1.The relationship then computes
Sensitivity × Pressure = L⁻² I, againstElectricPotential = M L² T⁻³ I⁻¹.Checking every
integrals/derivatives/dotProducts/crossProductsentry in the file: exactly four are dimensionally false, matching the set CLAUDE.md documents. Three are the rotational/angle cluster, which is structurally unfixable and correctly explained. This is the fourth, and it is not.What ships
The C++ projection refuses it —
Semantics.Cpp/QuantityVocabulary.cs:216-222, asserted bySemantics.Cpp.Test/CppQuantityGeneratorTests.cs:190-203.The .NET generator has no dimensional check at all. SEM001 verifies only that names resolve; there is no exponent arithmetic anywhere in
Semantics.SourceGenerators. So the operator is emitted into committed generated source:A caller writing
sensitivity * pressuregets aVoltageMagnitudeback — type-checked, and silently wrong by a factor carrying units ofm⁻⁵·kg⁻¹·s⁴·A².Why it matters
The point of the type system is that a dimensionally wrong product does not compile. Here it does, and yields a named quantity.
It also means the two projections of one metadata file disagree about what the vocabulary contains — at exactly the place the library promises they do not.
Suggested fix
Two separable pieces:
(a) Fix the metadata. This is a physics call between:
V/Pa—{"length": 3, "time": -1, "electricCurrent": -1}, matching the declared unit and making the relationship true; orA/Pa—{"mass": -1, "length": 1, "time": 2, "electricCurrent": 1}, which requires both the unit and the relationship to change.The
symbolstring needs updating either way, and CLAUDE.md's description of the bug needs its sign corrected.(b) Port the exponent check to the .NET generator as a new
SEM00x, so the two sides cannot diverge again. The arithmetic already exists inSemantics.Cpp/DimensionVector.cs; today a false relationship is caught only if it happens to reach the C++ projection.Part (b) is the more durable half — (a) fixes one entry, (b) makes the next one impossible to miss.