Skip to content

driver-sql's varchar-sizing type list and spec's BOUNDED_STRING_FIELD_TYPES must now agree, and nothing pins them — the same three-lists-disagree defect #11566 was filed for, one layer down #12017

Description

@os-warren

Found by the domain:engine seat's unlock scan while closing #11431. Filed unlabelled and unassigned for triage to grade — ⛔ an execution seat does not grade.

What changed to create this

Two things landed a day apart and now depend on each other, with no gate between them:

Measured on origin/main, the two lists are related but not identical, and the difference is deliberate on both sides:

list
spec BOUNDED_STRING_FIELD_TYPEStext, textarea, email, url, phone, password, markdown, html, richtext, code
driver varcharColumnCharsdeclaredVarcharLength (varchar-sized)string, email, url, phone, password
driver varcharColumnCharskeyableTextLength (TEXT unless keyed)text, textarea, html, markdown

So today they are consistent by reasoning: spec's list is "may declare a bound", the driver splits that into "gets a varchar" vs "gets TEXT". Nothing asserts that relationship, and the two files are owned by two different seats.

Why this is the #11566 defect one layer down

#11566 was filed precisely because three hand-maintained lists disagreed about where maxLength applies (field.form.ts 3 types, object.form.ts 9 types, record-validator 10 types). That card fixed the authoring half by making spec the single authority. It did not — and could not, from that lane — bind the driver to it.

⇒ The failure mode is now: spec adds a type to BOUNDED_STRING_FIELD_TYPES, the driver's switch does not learn about it, and the type silently falls to the catch-all table.string(name) at knex's 255 — which is exactly the defect #11431 existed to fix, re-entering through a different door and against a bound the platform now formally accepts.

⚠️ It is also the mechanism #11794's PR named on the neighbouring case, in its own words: "the hand-maintained list is what let one member of a three-member spec group diverge silently." That card pinned the driver's own set as a whole; nothing pins it against spec's.

Not claimed

  • No divergence exists today — the lists were read and are consistent. This is a missing guard, not a live defect, and it should not be described as one.
  • Which side should own the derivation is not decided here. Deriving the driver's switch from spec's constant is one option; a pin test that fails when the two drift is the cheaper one and needs no cross-package dependency. @objectstack/lint's contract forbids depending on a runtime, so a lint rule may not be the right home — worth checking rather than assuming.
  • ⚠️richtext and code are in spec's list but in neither driver branch today; PR fix(driver-sql): richtext and code take an unbounded TEXT column, restoring the declared Rich Content grouping #11876 (open, with triage) moves exactly those two into the text family. Whoever takes this should read that PR first — the shape of the guard depends on where those two land.

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions