From df30aa6935bce72f951d511acc9ec0a07656d4b1 Mon Sep 17 00:00:00 2001 From: aaltshuler Date: Mon, 25 May 2026 23:44:28 +0100 Subject: [PATCH] feat(lint): add OG-MF-105 / OG-MF-107 enum-migration codes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mint two schema-lint codes for the enum-migration planner work: - OG-MF-105 "narrow enum value set" (Validated): removing allowed enum variants — apply scans existing rows and fails loudly on a row holding a now-disallowed value. - OG-MF-107 "constrain String to enum" (Validated): tightening a free String to an enum — same validated-scan semantics. Both are appended to ALL_CODES and EMITTED_IN_V0. The OG-MF-106 doc is narrowed to mean a genuine scalar-type change only, now that enum value-set deltas are split out to 105/107. Co-Authored-By: Claude Opus 4.7 (1M context) --- crates/omnigraph-compiler/src/lint/codes.rs | 37 ++++++++++++++++++--- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/crates/omnigraph-compiler/src/lint/codes.rs b/crates/omnigraph-compiler/src/lint/codes.rs index e53bf31..b719236 100644 --- a/crates/omnigraph-compiler/src/lint/codes.rs +++ b/crates/omnigraph-compiler/src/lint/codes.rs @@ -98,9 +98,23 @@ pub const OG_MF_104: DiagnosticCode = DiagnosticCode { short: "tighten nullable to non-nullable", }; +/// Narrow an enum's value-set by removing one or more allowed values +/// (e.g. `enum(a, b, c)` → `enum(a, b)`). The physical column is +/// unchanged (enums are stored as `String`), but a pre-existing row may +/// hold a now-disallowed value. Validated tier: apply scans existing +/// rows and fails loudly (listing the offending value) rather than +/// silently dropping data. +pub const OG_MF_105: DiagnosticCode = DiagnosticCode { + code: "OG-MF-105", + family: Family::MF, + tier: SafetyTier::Validated, + default_severity: Severity::Error, + short: "narrow enum value set", +}; + /// Narrow a scalar (e.g. I64 → I32, F64 → F32). Lossy cast that may -/// truncate or overflow. Today emitted on any `prop_type` change since -/// the v1 planner doesn't yet distinguish widening from narrowing. +/// truncate or overflow. Emitted for a genuine scalar-type change +/// (enum value-set changes are handled by OG-MF-105 / OG-MF-107). pub const OG_MF_106: DiagnosticCode = DiagnosticCode { code: "OG-MF-106", family: Family::MF, @@ -109,14 +123,29 @@ pub const OG_MF_106: DiagnosticCode = DiagnosticCode { short: "narrowing scalar type", }; +/// Constrain a free `String` property to an `enum` (e.g. `status: String` +/// → `status: enum(open, closed)`). Tightening: existing rows may hold a +/// value outside the new set. Validated tier: apply scans existing rows +/// and fails loudly on the first out-of-set value. +pub const OG_MF_107: DiagnosticCode = DiagnosticCode { + code: "OG-MF-107", + family: Family::MF, + tier: SafetyTier::Validated, + default_severity: Severity::Error, + short: "constrain String to enum", +}; + /// All v0 catalog entries. Used for chassis-level invariants /// (uniqueness, family coverage). pub const ALL_CODES: &[DiagnosticCode] = &[ - OG_DS_101, OG_DS_102, OG_DS_103, OG_DS_104, OG_DS_105, OG_MF_103, OG_MF_104, OG_MF_106, + OG_DS_101, OG_DS_102, OG_DS_103, OG_DS_104, OG_DS_105, OG_MF_103, OG_MF_104, OG_MF_105, + OG_MF_106, OG_MF_107, ]; /// Codes actually emitted by the planner in v0 (i.e. not reserved). -pub const EMITTED_IN_V0: &[&str] = &["OG-DS-102", "OG-DS-103", "OG-DS-104", "OG-MF-103", "OG-MF-106"]; +pub const EMITTED_IN_V0: &[&str] = &[ + "OG-DS-102", "OG-DS-103", "OG-DS-104", "OG-MF-103", "OG-MF-105", "OG-MF-106", "OG-MF-107", +]; /// Look up a code by its string identifier. pub fn lookup(code: &str) -> Option<&'static DiagnosticCode> {