ADR-0015 — Field curation layer + JSON Schema for editor DX
Update date : 2026-06-02 06:52
Status: accepted (amends ADR-0001) Date: 2026-06-02
Context
ADR-0001 mirrors snowflake.core exactly (zero manual mapping, auto-sync on SDK changes). But the
SDK surface has warts that leak into the YAML — the main authoring pain point:
- Stringly-typed booleans —
auto_resumeis typedstr, soauto_resume: true(YAML bool) is rejected; the user must write"true". - Bare-string enums —
warehouse_sizeisstr, so a typo (XSAMLL) is only caught atapplytime, and the editor offers no autocomplete. - Display-form echoes — Snowflake returns
X-Smallfor a declaredXSMALL(and2X-LargeforXXLARGE), which a naive diff reads as a perpetualALTER.
These were all found by running apply against a real account during the warehouse slice.
Decision
Two complementary, opt-in mechanisms — declared per resource, only for the warts (the other ~95% of fields stay auto-synced from the SDK):
_field_overrides—field → (clean Pydantic type, caster back to SDK form). The clean type is used for the model field (so the YAML is idiomatic and the JSON Schema autocompletes it); the caster restores the SDK string into_sdk_dict(). E.g.auto_resume: (bool, str→"true"),warehouse_size: (WarehouseSize, enum→value)._field_normalizers—field → comparison functionfor the diff engine, so display forms compare equal (warehouse_sizevia a size canonicaliser handlingX-Small,2X-Large,4X-Large). The diff comparesto_sdk_dict()— the exact payload Snowflake receives.
Enums are curated as soft enums — the field type is Enum | str (e.g. WarehouseSize | str).
The editor autocompletes the known values, but an unknown/future value still passes and is validated
by Snowflake at apply. This keeps forward-compatibility (a new Snowflake tier is never blocked by a
stale enum) and avoids the vendor-lock-in trap, at the cost of catching typos at apply instead of
authoring time. The JSON Schema is generated from the curated models (pinky-provider schemas)
and wired to the YAML language server; for a soft enum it emits anyOf: [enum, string] → value
autocomplete and no hard error on unknown values.
Consequences
- YAML stays clean (
auto_resume: true,warehouse_size: XSMALL) while the SDK gets its string forms. - The schema is generated, never hand-maintained → stays in sync with the SDK and the overrides.
- Amends ADR-0001: "pure mirror" → "mirror + thin curation". The inverted-maintenance property holds — only warts are annotated; a new SDK field still appears for free; a new warehouse tier is one line.
- Trade-off accepted: soft enums autocomplete without blocking, so typos pass model validation and
surface at
apply(Snowflake returns a clear error). Forward-compatibility and no lock-in are preferred over author-time typo rejection — a deliberate alignment with pinky's anti-lock-in thesis.