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
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). Routeddomain:specby the anchoring rule (every change underpackages/specgoes to the spec seat) under the maintainer's ruling;pm:queue. ⛔ Not claimed.The defect this narrows away
GroupingFieldSchema.field(packages/spec, thegrouping.fields[]block of list-view metadata) is a barez.string():' business_unit 'is valid authored metadata. Measured on objectui (comment 5607077319, M1–M11 with live controls): the projection harvestercollectGroupingFieldRefstrims the name for$select, while three renderers bucket rows by the raw name — plugin-gridusableGroupingFields, plugin-listObjectGallery.groupedItems, plugin-kanbaneffectiveSwimlaneField. The server answers underbusiness_unit, the readers look up' business_unit ', every row readsundefined, and the view shows one(empty)group (grid, gallery) or oneUncategorizedlane (kanban) holding every record — a silent wrong answer that reads as a true statement about the data. The siblinggroupByFieldaxis (kanban / gantt / timeline) is symmetric and is ⛔ not this card.The ruling
C — refuse at the producer.
GroupingFieldSchema.fieldgets a non-padded pattern (no leading/trailing whitespace; the same shape the field-name vocabulary already uses elsewhere inpackages/specif 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
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-②: yesby 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).Cross-repo landing
objectui#7347 is
pm:blockedon 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