CultivationSetup has five paired *_unit slots — working_volume_unit, operating_temperature_unit, feed_or_dilution_rate_unit, retention_time_unit, and retention_time_type — and every one has no range, so it is a free-text string. linkml-validate accepts anything.
The drift is already here. Adding two records in the #183 sweep, I wrote retention_time_unit: HOURS and feed_or_dilution_rate_unit: PER_HOUR — enum-shaped, because the neighbouring slots (cultivation_mode, system_type) are enums and the shape of the block invites it. The corpus already had h, d, L/day, mL, L: unit symbols. Nothing failed. I only noticed by grepping the corpus for what other records had used.
Normalized to symbols in the PR that found it, so the 11 populated slots agree today. That is a snapshot, not a fix — the next curator has the same 50/50 and no feedback either way.
Why it matters beyond tidiness: a numeric field whose unit is unconstrained cannot be compared across records or exported to a KG without a per-record lookup of what the string meant. retention_time: 12 is not a quantity until h is machine-readable. Two records that disagree on spelling are two records that silently do not join.
Options, roughly in order of cost:
- Enums per dimension —
TimeUnitEnum {h, d, min}, VolumeUnitEnum {L, mL}, RateUnitEnum {1/h, L/day}, TemperatureUnitEnum {C, K}. Cheapest, matches how cultivation_mode and system_type already work, and makes the block internally consistent in style. Downside: a new unit needs a schema change.
- UCUM —
structured_pattern or a validator against UCUM codes. Correct in the general case and already the convention in adjacent projects; more machinery than five slots justify today.
- A test pinning the observed vocabulary — cheapest of all, catches drift, but records a convention rather than enforcing one, and does nothing for export.
retention_time_type is a different question — its values so far are HYDRAULIC and (elsewhere) solids-retention senses, which is a small closed enum rather than a unit.
Related to #182 in kind: a slot that looks controlled but is not.
CultivationSetuphas five paired*_unitslots —working_volume_unit,operating_temperature_unit,feed_or_dilution_rate_unit,retention_time_unit, andretention_time_type— and every one has no range, so it is a free-text string.linkml-validateaccepts anything.The drift is already here. Adding two records in the #183 sweep, I wrote
retention_time_unit: HOURSandfeed_or_dilution_rate_unit: PER_HOUR— enum-shaped, because the neighbouring slots (cultivation_mode,system_type) are enums and the shape of the block invites it. The corpus already hadh,d,L/day,mL,L: unit symbols. Nothing failed. I only noticed by grepping the corpus for what other records had used.Normalized to symbols in the PR that found it, so the 11 populated slots agree today. That is a snapshot, not a fix — the next curator has the same 50/50 and no feedback either way.
Why it matters beyond tidiness: a numeric field whose unit is unconstrained cannot be compared across records or exported to a KG without a per-record lookup of what the string meant.
retention_time: 12is not a quantity untilhis machine-readable. Two records that disagree on spelling are two records that silently do not join.Options, roughly in order of cost:
TimeUnitEnum {h, d, min},VolumeUnitEnum {L, mL},RateUnitEnum {1/h, L/day},TemperatureUnitEnum {C, K}. Cheapest, matches howcultivation_modeandsystem_typealready work, and makes the block internally consistent in style. Downside: a new unit needs a schema change.structured_patternor a validator against UCUM codes. Correct in the general case and already the convention in adjacent projects; more machinery than five slots justify today.retention_time_typeis a different question — its values so far areHYDRAULICand (elsewhere) solids-retention senses, which is a small closed enum rather than a unit.Related to #182 in kind: a slot that looks controlled but is not.