Schemagen: support shared/named enum types to eliminate cross-schema enum conversion bugs
Context
MIR-940 exposed a class of bug where the same semantic enum (disk provider: miren | local) is defined inline in two schema paths, causing schemagen to generate two separate Go types with different string constant values:
DisksProviderwith value"provider.miren"ConfigSpecServicesDisksProviderwith value"component.config_spec.services.disks.provider.miren"
Go happily allows type conversion between them since they're both string underneath, but the values silently mismatch. We hit this bug in three separate places across two PRs (#713, #714) before fully fixing it — each boundary between schema layers required a hand-written switch to map between representations.
Proposal
Add support for named, reusable enum definitions in schema YAML:
enums:
disk_provider:
choices: [miren, local]
doc: "Disk provider: 'miren' for network disks, 'local' for node-local"
kinds:
config_spec:
services:
disks:
provider:
type: enum
ref: disk_provider
Schemagen would generate one Go type per named enum, with the semantic values as constants ("miren", "local") rather than path-prefixed strings. The Encode()/Decode() functions would bridge between the shared Go constants and the per-path entity store IDs.
This eliminates the entire class of bug — there's one type, one set of values, and the compiler enforces consistency across schema boundaries.
Migration considerations
- Entity store data: No change. The fully-qualified entity IDs in etcd stay the same —
Encode()/Decode()just map differently. - Rolling deploys: Safe, since
Decode()maps from entity IDs (unchanged) to Go constants (new values). Old and new code read the same stored data. - Code churn: One-shot
make generate+ fix compile errors. Mechanical but potentially noisy. - Wire format: Audit whether any RPC messages serialize Go enum values directly (not via entity store). If so, those would see different on-wire strings during the transition.
References
- MIR-940 / PR #713 / PR #714 — the bug that motivated this
pkg/entity/cmd/schemagen/generator.golines 636-675 — current enum generation logicapi/core/schema.yml— the two inline disk provider enum definitions