Problem
haystack-core/data/units.txt is a fairly complete Haystack units database — 457 unit entries across 61 -- quantity -- sections (dimensionless, currency, acceleration, angular acceleration/momentum/velocity, area, capacitance, cooling efficiency, density, electric charge/conductance/current/field strength/potential/resistance, electrical conductivity/resistivity, energy (+ apparent/reactive/by-area/by-volume), enthalpy, entropy, force, frequency, grammage, heating rate, illuminance, inductance, irradiance, length, luminance, luminous flux/intensity, magnetic field strength/flux/flux density, mass, mass flow, momentum, power (+ by-area/by-volumetric-flow/apparent/reactive), pressure, specific entropy, surface tension, temperature (+ differential), thermal conductivity, time, velocity, volume, volumetric flow, bytes). Name/symbol lookup (unit_for) covers this whole set.
But haystack-core/src/kinds/units.rs's CONVERSION_FACTORS table — the thing convert() and compatible() actually use — is a hand-written array covering only 15 quantities (temperature, length, pressure, energy, power, volume, volumetric flow, area, mass, time, electric current, electric potential, frequency, illuminance, luminous flux), roughly 90 of the 457 registered units:
static CONVERSION_FACTORS: LazyLock<HashMap<&'static str, ConversionFactor>> =
LazyLock::new(|| {
let entries: &[(&str, f64, f64)] = &[
// temperature (SI base: celsius)
("fahrenheit", 5.0 / 9.0, -32.0 * 5.0 / 9.0),
...
];
...
});
resolve() returns UnitError::UnknownUnit for any unit whose name is valid (parses via unit_for) but has no entry here — e.g. currency (USD, EUR), density (kg/m³), velocity (m/s), force (newton), entropy, capacitance, inductance, magnetic_flux, bytes, etc.
Impact
Downstream unit-bearing comparisons or conversions (e.g. normalizing energy density, flow velocity, or currency-tagged cost points) silently fail with UnitError::UnknownUnit/compatible() == false for the ~46 uncovered quantities, even though the unit names themselves are recognized elsewhere in the API (unit_for, quantity()). Verdant must special-case or app-side implement conversion for any quantity outside the 15-dimension list, and there is no documented boundary between "units known by name" and "units convertible."
Proposed direction
Either (a) generate CONVERSION_FACTORS from the same units.txt source (Project Haystack's reference units database typically ships SI conversion factors per unit) so the two tables can't drift, or (b) explicitly document/gate which quantities are convertible and have quantity()/unit_for() signal it (e.g. a has_conversion_factor(name) query) so callers can detect the gap before calling convert().
References
Project Haystack units database (units.txt reference format, quantity-sectioned).
Problem
haystack-core/data/units.txtis a fairly complete Haystack units database — 457 unit entries across 61-- quantity --sections (dimensionless, currency, acceleration, angular acceleration/momentum/velocity, area, capacitance, cooling efficiency, density, electric charge/conductance/current/field strength/potential/resistance, electrical conductivity/resistivity, energy (+ apparent/reactive/by-area/by-volume), enthalpy, entropy, force, frequency, grammage, heating rate, illuminance, inductance, irradiance, length, luminance, luminous flux/intensity, magnetic field strength/flux/flux density, mass, mass flow, momentum, power (+ by-area/by-volumetric-flow/apparent/reactive), pressure, specific entropy, surface tension, temperature (+ differential), thermal conductivity, time, velocity, volume, volumetric flow, bytes). Name/symbol lookup (unit_for) covers this whole set.But
haystack-core/src/kinds/units.rs'sCONVERSION_FACTORStable — the thingconvert()andcompatible()actually use — is a hand-written array covering only 15 quantities (temperature, length, pressure, energy, power, volume, volumetric flow, area, mass, time, electric current, electric potential, frequency, illuminance, luminous flux), roughly 90 of the 457 registered units:resolve()returnsUnitError::UnknownUnitfor any unit whose name is valid (parses viaunit_for) but has no entry here — e.g.currency(USD,EUR),density(kg/m³),velocity(m/s),force(newton),entropy,capacitance,inductance,magnetic_flux,bytes, etc.Impact
Downstream unit-bearing comparisons or conversions (e.g. normalizing energy density, flow velocity, or currency-tagged cost points) silently fail with
UnitError::UnknownUnit/compatible() == falsefor the ~46 uncovered quantities, even though the unit names themselves are recognized elsewhere in the API (unit_for,quantity()). Verdant must special-case or app-side implement conversion for any quantity outside the 15-dimension list, and there is no documented boundary between "units known by name" and "units convertible."Proposed direction
Either (a) generate
CONVERSION_FACTORSfrom the sameunits.txtsource (Project Haystack's reference units database typically ships SI conversion factors per unit) so the two tables can't drift, or (b) explicitly document/gate which quantities are convertible and havequantity()/unit_for()signal it (e.g. ahas_conversion_factor(name)query) so callers can detect the gap before callingconvert().References
Project Haystack units database (
units.txtreference format, quantity-sectioned).