Skip to content

spec: GroupingFieldSchema.field accepts a padded field name that three objectui readers bucket wrong — refuse non-trimmed names at the producer (ruling C on objectui#7347) #17360

Description

@os-litant

Filed by the director seat (summon #21, session_01QVMnxyWBx8cAQMsV6akDV9) as the protocol card for ruling C on objectui#7347 — maintainer verbatim 「其他同意」 on decision batch #110 item 5 (director chat, 2026-09-10T08:4xZ; analysis and options at objectui#7347 comment 5615378321). Routed domain:spec by the anchoring rule (every change under packages/spec goes to the spec seat) under the maintainer's ruling; pm:queue. ⛔ Not claimed.

The defect this narrows away

GroupingFieldSchema.field (packages/spec, the grouping.fields[] block of list-view metadata) is a bare z.string(): ' business_unit ' is valid authored metadata. Measured on objectui (comment 5607077319, M1–M11 with live controls): the projection harvester collectGroupingFieldRefs trims the name for $select, while three renderers bucket rows by the raw name — plugin-grid usableGroupingFields, plugin-list ObjectGallery.groupedItems, plugin-kanban effectiveSwimlaneField. The server answers under business_unit, the readers look up ' business_unit ', every row reads undefined, and the view shows one (empty) group (grid, gallery) or one Uncategorized lane (kanban) holding every record — a silent wrong answer that reads as a true statement about the data. The sibling groupByField axis (kanban / gantt / timeline) is symmetric and is ⛔ not this card.

The ruling

C — refuse at the producer. GroupingFieldSchema.field gets a non-padded pattern (no leading/trailing whitespace; the same shape the field-name vocabulary already uses elsewhere in packages/spec if one exists — reuse it, do not invent a second), with a refusal message naming the field and the offending spelling. ⛔ Not .trim(): a trimming schema makes ' a ' and 'a' silently equivalent, which is the consumer-tolerance direction AGENTS.md #0.1 refuses. The harvester's trim on the objectui side stays as defence-in-depth; nothing is removed there.

Governing text: AGENTS.md #0.1 (fix the producer, do not teach the renderer to tolerate); 2026-08-27 maintainer ruling 「短期不考虑渐进」 — the narrowing ships at once, no deprecation window.

Acceptance

  • A refusal pin: a padded grouping field name is refused by name at grouping.fields[N].field; control: the clean name still parses, and every existing grouping fixture in the repo still parses (enumerate them — a narrowing that reddens an in-tree fixture is a finding, report it, do not widen the pattern to fit).
  • Clause-②: yes by the conservative routing precedent for spec narrowings (objectui#8285 ruling: a spec narrowing declares yes; minor + BREAKING note in the changeset, ADR-0087 disposition: stored metadata with a padded name now fails validation and must be re-authored — say so in the changeset).
  • Changeset names objectui#7347 as the consumer that unblocks on the installable release, not on merge.

Cross-repo landing

objectui#7347 is pm:blocked on this card (Blocked-by: in its body). On release the objectui side is a pin bump plus a regression test that a padded name is refused before it reaches any renderer; the gallery and kanban sites are covered by this one producer fix and get no cards of their own (dev's reasoning at objectui#7347 5607077319, endorsed).


Generated by Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions