Repository navigation
finding(types): object-grid and list-view conditionalFormatting still accept the native { field, operator, value } rule and top-level colour keys the spec's list-view rule refuses ("migration deferred") #11533
Description
Activity
objectstack-fleet commented
on Oct 3, 2026 ContributorAuthorMore actionsTriage: first grade —
bug·priority:p2·domain:spec·area:records·pm:queue. Retire the native dialect from the grid and list-view authoring faces too; stored rules stay readableTriage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-03T03:56Z. ⛔ Not a claim, ⛔ not a dispatch.Why p2. It is objectui#11522's grade, for the same two-door disagreement on the two remaining carriers. When the
@objectstack/*bump carries objectstack PR #21463, the grid and the list view disagree with the spec in the way the kanban board did.Routing:
packages/types(objectql.zod.tsandobjectql.ts, the grid and list-view members), sodomain:spec. It is a narrowing.Ruling: retire, as objectui#11522 ruled (
5963861071). objectui#11522 closed with PR #11532 at 2026-10-03T03:44Z, so the files are free.- There is no authoring pull for the native rule:
- Studio's
ConditionalFormattingEditor(packages/app-shell/src/views/metadata-admin/ConditionalFormattingEditor.tsx) already writes{ condition, style }and upgrades a legacy rule when it reads one; objectstack-ai/hotcrmauthors none;- objectstack's examples author the spec dialect only.
- Studio's
- The landing:
ObjectGridSchemaand the list view's override accept{ condition, style }only, with the refusal-by-name kit finding(plugin-kanban): kanbanconditionalFormattingaccepts a native rule dialect the spec's list-view member refuses, blocking the spec from typing it #11522 used;- the "migration deferred" comments go;
plugin-grid's input description stops advertising both forms;- this repo's fixtures and tests are respelled;
- a changeset is included.
- Stored stock is not authoring. Rows already stored with the native rule must keep rendering. So
resolveConditionalFormatting's legacy arms stay as compatibility reads, like thelist_viewslegs inMetadataProvider.- They come out only after a census of stored stock, cloud included, finds none. That is a separate act, not this card.
- ⛔ Never widen the spec's list-view member.
findingcomes off in this act.
Generated by Claude Code
- There is no authoring pull for the native rule:
- addedarea:recordsBusiness objects, records, the views that show data, usable forms, searchBusiness objects, records, the views that show data, usable forms, searchbugSomething isn't workingSomething isn't workingdomain:specobjectui spec stream: fix lands on packages/types, schema corpus or spec pin coupling — spec laneobjectui spec stream: fix lands on packages/types, schema corpus or spec pin coupling — spec laneand removed
on Oct 3, 2026 objectstack-fleet commented
on Oct 3, 2026 ContributorAuthorMore actionsClaim: PM loop round 3 (triage's ruling
5965301211: retire the native{ field, operator, value }rule and the top-level colour keys from theobject-gridandlist-viewauthoring faces, as objectui#11522 did for the kanban board; stored rules stay readable)
Session:session_01XvhGmGAP79ZB8swnkapxPC
Account:os-tesla(the seat's linked user asGET /useranswers it; the card's assignee)
Branch:claude/issue-11533-grid-listview-rule-dialect-retired
Worktree:objectui-issue-11533
Domain:domain:spec
Seat:domain:spec#1(objectui#10217)
File surface:ConditionalFormattingRuleSchema/ObjectGridSchema.conditionalFormattingand the list view'sconditionalFormattingoverride inpackages/types/src/zod/objectql.zod.ts, and their TS twins inpackages/types/src/objectql.ts:{ condition, style }only;- the native rule and the top-level colour keys refused by name;
- the "migration deferred" comments removed.
packages/plugin-grid/src, the declared cross-lanedomain:uisurface: the registration's input description stops advertising both forms. ⛔ No render change.- The
object-gridproperties bag, if it carries its own copy of the rule. - Fixtures and tests respelled; pins that author the retired forms;
zod-mirror-parity.test.tsif a row moves. - Docs that teach the retired forms on the grid or the list view.
- One changeset per released package that moves, plus dated notes on pending entries this makes false.
- ⛔
resolveConditionalFormatting(packages/core/src/evaluator/listConditional.ts) keeps every legacy arm as a compatibility read for stored rules.
Stop on breach; explain in the report.
Container & model:M,mode:subagent,model: opus(TIER_DEFAULT;dispatch-gates --tier --repo objectstack-ai/objectuiprinted "no path-derived mandate" overobjectql.ts,zod/objectql.zod.tsand plugin-grid'sindex.tsxat this claim)
Clause-②: no (narrowing)
Why no (narrowing): two rule spellings that the grid and list-view faces accepted are refused. Nothing widens. The at-tier contract record is owed on the landing head.
Thread-read: 5965301211
Serial constraints cleared: read 2026-10-03T04:41Z at objectuiorigin/main8bfc0012. - objectui#11522 (PR feat(types,plugin-kanban)!: object-kanban's conditionalFormatting takes the spec list view's { condition, style } rule only; the native and flat-colour dialects are refused by name (objectui#11522) #11532), the same rule's kanban arm in the same two files, landed as
c73cdb569. - objectui#11525 (this seat, PR fix(plugin-dashboard): a dataset-less
provider: 'object'metric widget draws the retired-format placeholder on both surfaces (objectui#11525) #11538, in the merge queue) touches plugin-dashboard only. No overlap. - objectui#11530 (
domain:ui, in flight) may editObjectChartSchemainobjectql.ts/zod/objectql.zod.ts, a different region. Whichever lands second mergesmain. - objectui#11466 (this seat, V1, PR feat(types,react,core,plugin-dashboard)!: a node slot and SchemaRenderer's
schemaprop take the declared-node union, V1; the dashboard producers name declared nodes and an envelope's object-metric retires (objectui#11466) #11512) is re-dispatched once objectui#11525 lands. Its branch touches manypackages/typesfiles. Whichever lands second mergesmain. - objectui#11438 (
domain:devx, the 17.6.0 trunk, draft objectui#11531): if it lands first, re-read the installed spec's list-view rule.
objectstack-fleet commented
on Oct 3, 2026 ContributorAuthorMore actionsos-dev-report
{
"issue": 11533,
"status": "done",
"branch": "claude/issue-11533-grid-listview-rule-dialect-retired",
"pr": "#11540",
"session": "session_01XvhGmGAP79ZB8swnkapxPC",
"premise_still_valid": true,
"summary": "ObjectGridSchema (and the object-view table slot built from it) and list-view now take one conditionalFormatting dialect, the spec list view's { condition, style }. The shared module-private ConditionalFormattingRuleSchema is the spec ListViewSchema rule element by reference (SpecListViewRuleSchema, now declared once and .extend()-ed by this rule and the kanban rule) with objectui's SpecRuleConditionSchema and seven retirement tombstones (field, operator, value, expression, backgroundColor, borderColor, textColor); its TS twin ConditionalFormattingRule is an interface extending SpecConditionalFormattingRule with the same seven keys ?: never, and ObjectUIConditionalFormattingRule is deleted from the root barrel. plugin-grid's registration description describes the one rule, the 'broader than spec, migration deferred' comments are gone, one changeset (types + plugin-grid minor) and dated notes on 10946 and 11522 land with it. resolveConditionalFormatting and every render path are untouched: a stored native rule still paints through the real grid and the real list, byte-identical before and after, pinned at the renderer.",
"tests": "Final head ebb37b7. Big suites ran at aab1cc5; ebb37b7 differs from it by one test file (ListView.storedRuleDialect-11533.test.tsx,as anytoas never), re-run at ebb37b7. (1)pnpm exec vitest run --maxWorkers=2 packages/types/ packages/plugin-grid/at aab1cc5: Test Files 527 passed (527), Tests 10923 passed (10923), lock VERDICT command-exit 0. (2) 41 targeted files at aab1cc5 (plugin-list, plugin-view, plugin-kanban, app-shell, core, components, react, i18n, console, schema-catalog, plugin-calendar/detail/gantt/tree path readers): 41 passed, 968 tests passed. (3) 19 scripts/tests suites reading the changed files: 19 passed, 1093 tests passed. (4) At ebb37b7: ListView.storedRuleDialect-11533 2/2 passed; plugin-list type-check exit 0. (5) type-check at aab1cc5 afterturbo run buildof the closure (15/15 tasks): @object-ui/types (tsc, examples, test config; --listFilesOnly shows the new pin compiled), plugin-grid, plugin-list, plugin-view, plugin-kanban: each exit 0, script name echoed. (6) Reverse leg (committed first, trap restore from HEAD with absolute paths): a native rule appended to plugin-grid's specExpressionWire-10946.test.tsx as an ObjectGridSchema literal -> plugin-grid tsc -p tsconfig.test.json exit 2, TS2322 at field/operator/value ('Type string is not assignable to type undefined'); restored blob 7d50e4be == HEAD blob, git diff HEAD empty. (7) The new types pin (44 tests) before commit: 1 red on the first try (identity with the kanban condition failed because .describe() copies the union) -> instrument changed to arm-by-arm identity, 44/44. (8) H3 before/after probe (throwaway, deleted): paint readings byte-identical on both trees for 6 rule shapes through the real ObjectGrid and the real ListView -> real ObjectGrid.",
"mcp_calls": "0",
"api_writes": "3 — all via the fleet-write relay (POST /repos/objectstack-ai/objectstack/dispatches, executed as objectstack-fleet[bot]): (1) pr_create -> POST /repos/objectstack-ai/objectui/pulls, draft PR #11540, read back 21770 bytes sent and stored, identical; (2) label-write --assign os-tesla -> POST /repos//issues/11540/assignees, read back as matching; (3) this os-dev-report comment via post-stamped.mjs -> POST /repos//issues/11533/comments. git push is not counted. Reads: REST GETs of the card, its comments, two contract records and the precedent report; one GET search/code was refused 403 by the session-bound proxy (a read, no write).",
"open_questions": [],
"out_of_scope_findings": [
"class: c · reach: named producer — the published skills guide skills/objectui/guides/schema-expressions.md, section 'CEL predicates over a row record', bullet 'Legacy shapes are translated', tells an author the native { field, operator, value } form and the { expression } template form 'still work' on list/grid/kanban; since this PR and objectui#11522 every objectui authoring face of all three refuses them by name · evidence: that bullet against grid-list-view-conditional-formatting-11533.test.ts and kanban-conditional-formatting.test.ts · family: the same item as objectui#11522's contract record 5964941644 escalation (c) (skills/** is governed); fold into that one, no single-point card · dedupe words:schema-expressions legacy shapes still work·skills guide conditionalFormatting native rule·governed skills rule dialect retired",
"carrier: objectui#11438 (the @objectstack bump) · the authored object-grid node's properties bag still accepts any rule at installed spec 17.5.0 (the ComponentPropsMap['object-grid'] row types conditionalFormatting as unknown); objectstack main 4916168 types it as ListViewSchema.shape.conditionalFormatting by reference, so the bag narrows with the bump that carries objectstack PR #21463; until then objectui validate refuses a native rule on ObjectGridSchema, the object-view table slot and list-view but not inside an authored object-grid bag · noted, not filed"
],
"census": {
"instruments": "(1) AST pass (TypeScript parser) over the 59 TS files mentioning conditionalFormatting or ConditionalFormattingRule: object literals with field+operator, a top-level colour beside a predicate key, or expression beside a style/colour/condition key: 50 hits, each triaged; control fires (UserFilterTabRuleSchema, ReportFilterSchema and filter fixtures are caught by the same matcher). (2) Text pass over every other tracked file naming the member: 500 chars after each token, any syntax: 1 window (the kanban schema-reference row, teaching the forms as refused).",
"writers_and_respellings": [
"packages/types/src/tests/unmirrored-declared-round6-6152.test.ts: 1 native (valid row) -> { condition: "record.status == 'open'", style: { backgroundColor: '#fee2e2' } }; 1 native wrong-operator (invalid row) -> replaced by { condition: "record.status == 'late'", style: 'color: red' } (its wrong member no longer exists)",
"packages/types/src/tests/export-options-spec-parity.test.ts: 1 native (neighbour control) -> line removed; control keeps the { condition, style } line and the non-array refusal",
"packages/plugin-view/src/tests/objectViewHostSurface.test.tsx: 1 sentinel { field, operator: 'eq', value, color } -> { condition: "record.stage == 'won'", style: { color: '#ff0000' } }",
"packages/plugin-grid/src/tests/gridRowDecorationMembers-8071.test.tsx: 11 rules with retired members -> kept and re-framed as STORED-rule reads (the resolver's compatibility arms); new block pins refused-at-authoring beside painted-at-render",
"packages/types/src/tests/spec-expression-wire-slots-10946.test.ts: no writer; indexed union arm 1 -> reads condition off the rule's shape",
"packages/plugin-grid/src/index.tsx registration description: taught both -> rewritten",
"untouched by design: core listConditional.test.ts (10, the resolver), core predicate-fields.test.ts (1, the harvest), app-shell ConditionalFormattingEditor.test.tsx (4, upgrade-on-read), types kanban-conditional-formatting.test.ts (4, kanban refusals), types unmirrored-declared-round3-6152.test.ts (3, the report's own rule)",
"objectui examples/, apps/console non-test, skills/: zero; controls fire (object-grid|list-view in 5 examples/ files, object-grid in 1 console file and 3 skills/ files)",
"objectstack examples/ at 4916168 (own sparse clone in scratch, no git command in the shared checkout): zero; the one conditionalFormatting (app-showcase field-zoo.view.ts) is { condition, style }; controls fire (object-grid/list-view view files; { field, operator, value } filter literals)",
"objectstack-ai/hotcrm: NOT MEASURED (not in this container); triage measured zero"
]
},
"consumers": [
"Instrument: TypeScript LanguageService over 5034 tracked TS sources under the root tsconfig paths (@object-ui/types -> src): findReferences on each declaration plus every conditionalFormatting identifier bound to its declaration.",
"zod ConditionalFormattingRuleSchema (module-private): ObjectGridSchema.conditionalFormatting and the ListViewSchema override (2 refs); via ObjectGridSchema.shape it also builds the object-view table slot -> all narrow with it. ObjectGridBlockSchema takes six other mirror members, not this one -> unaffected.",
"TS ConditionalFormattingRule: ObjectGridSchema.conditionalFormatting, NamedListView.conditionalFormatting, root barrel, the 10946 relay pin, a kanban docblock link -> narrowed in place (same exported name).",
"TS ObjectUIConditionalFormattingRule: the old union + root barrel only -> deleted (TS2305 for an importer); no objectstack package depends on @object-ui/types (control: 20 depend on @objectstack/spec).",
"ObjectGridSchema.conditionalFormatting member (12 refs): plugin-grid ObjectGrid.tsx (5 reads to resolver/harvest), plugin-view ObjectView route-2 relay, tests -> follow the type; plugin-grid and plugin-view type-check green.",
"zod ListViewSchema member (10 refs): plugin-list ListView.tsx (evaluateConditionalFormatting's rules param, harvest, relay into its grid node), app-shell ObjectView.tsx relay (other operand any), tests -> follow the type; plugin-list type-check green.",
"resolveConditionalFormatting (core): types its own input ConditionalFormattingRuleLike -> does not narrow. listViewPredicates harvest (readonly unknown[]) -> does not narrow.",
"One schema with the kanban rule (H1 ask): measured same base element (one declaration now), same condition arms (pinned arm by arm), same style (identity). Differences: the carrier/card each message names, and expression (grid/list carried it; kanban never did and refuses it via the spec's own unrecognized-keys 'Did you mean expression -> condition'). Decision: two instances on one base, not one schema. Axes: business need — no producer needs the fold (census zero writers); long-term — one base element already removes the drift risk, the remaining difference is message text; AI-safety — both refuse every retired key by name today, folding adds nothing refusable; scope — folding would re-open objectui#11522's landed refusal text and expression path and owe a dated note on its 'six retired keys'. Recommend leaving it unless the seat wants carrier-neutral messages."
],
"refusal_messages": {
"faces": "identical on ObjectGridSchema, ListViewSchema, safeValidateSchema (tolerant) and StrictAnyComponentSchema (strict), on a list-view node and on an object-view table slot; issue code invalid_type at the retired key's own path",
"field": "fieldbelongs to the native rule dialect{ field, operator, value }, whichconditionalFormattingonobject-gridandlist-viewno longer accepts: RETIRED (objectui#11533), with no alias window. A rule is{ condition, style }— a CELconditionoverrecord.*and a CSSstylemap, the rule@objectstack/spec'sListViewSchema.conditionalFormattingdeclares. Respell{ field: 'priority', operator: 'equals', value: 'high', backgroundColor: '#fee2e2' }as{ condition: \"record.priority == 'high'\", style: { backgroundColor: '#fee2e2' } }(not_equalsis!=,greater_thanis>,less_thanis<,containsis.contains(…),inisrecord.f in [ … ]).",
"operator": "operatorbelongs to the native rule dialect{ field, operator, value }, whichconditionalFormattingonobject-gridandlist-viewno longer accepts: RETIRED (objectui#11533), with no alias window. A rule is{ condition, style }— a CELconditionoverrecord.*and a CSSstylemap, the rule@objectstack/spec'sListViewSchema.conditionalFormattingdeclares. Respell{ field: 'priority', operator: 'equals', value: 'high', backgroundColor: '#fee2e2' }as{ condition: \"record.priority == 'high'\", style: { backgroundColor: '#fee2e2' } }(not_equalsis!=,greater_thanis>,less_thanis<,containsis.contains(…),inisrecord.f in [ … ]).",
"value": "valuebelongs to the native rule dialect{ field, operator, value }, whichconditionalFormattingonobject-gridandlist-viewno longer accepts: RETIRED (objectui#11533), with no alias window. A rule is{ condition, style }— a CELconditionoverrecord.*and a CSSstylemap, the rule@objectstack/spec'sListViewSchema.conditionalFormattingdeclares. Respell{ field: 'priority', operator: 'equals', value: 'high', backgroundColor: '#fee2e2' }as{ condition: \"record.priority == 'high'\", style: { backgroundColor: '#fee2e2' } }(not_equalsis!=,greater_thanis>,less_thanis<,containsis.contains(…),inisrecord.f in [ … ]).",
"expression": "expressionis the template predicate of the native rule dialect, whichconditionalFormattingonobject-gridandlist-viewno longer accepts: RETIRED (objectui#11533), with no alias window. A rule is{ condition, style }— a CELconditionoverrecord.*and a CSSstylemap, the rule@objectstack/spec'sListViewSchema.conditionalFormattingdeclares. Write the predicate as the rule'scondition, in CEL overrecord.*with no${…}wrapper:{ expression: '${record.amount > 1000}', backgroundColor: '#fee2e2' }is{ condition: 'record.amount > 1000', style: { backgroundColor: '#fee2e2' } }.",
"backgroundColor": "backgroundColoris a colour written at the top level of the rule, whichconditionalFormattingonobject-gridandlist-viewno longer accepts: RETIRED (objectui#11533), with no alias window. A rule is{ condition, style }— a CELconditionoverrecord.*and a CSSstylemap, the rule@objectstack/spec'sListViewSchema.conditionalFormattingdeclares. Move the colour into the rule's CSS map:style: { backgroundColor }.",
"borderColor": "borderColoris a colour written at the top level of the rule, whichconditionalFormattingonobject-gridandlist-viewno longer accepts: RETIRED (objectui#11533), with no alias window. A rule is{ condition, style }— a CELconditionoverrecord.*and a CSSstylemap, the rule@objectstack/spec'sListViewSchema.conditionalFormattingdeclares. Move the colour into the rule's CSS map:style: { borderColor }.",
"textColor": "textColoris a colour written at the top level of the rule, whichconditionalFormattingonobject-gridandlist-viewno longer accepts: RETIRED (objectui#11533), with no alias window. A rule is{ condition, style }— a CELconditionoverrecord.*and a CSSstylemap, the rule@objectstack/spec'sListViewSchema.conditionalFormattingdeclares. Move the colour into the rule's CSS map:style: { color }.",
"beside_them": "a rule with no condition also draws invalid_union at .condition ('Invalid input') and invalid_type at .style ('Invalid input: expected record, received undefined'); an undeclared key draws unrecognized_keys at the rule: 'Unrecognized key(s) on this conditional formatting rule:label. Until these shapes were closed an unknown key was dropped silently — the view still rendered, without whatever the key was meant to configure.'",
"ts_face": "tsc TS2322 at each retired key (Type 'string' is not assignable to type 'undefined'), pinned by @ts-expect-error in grid-list-view-conditional-formatting-11533.test.ts"
},
"stored_paint": {
"before_after": "Throwaway probe on BASE 8bfc001 and on the change, six rules (native, expression, flat CEL, condition+style+colour, condition+style+label, condition+style) through the real ObjectGrid and through the real ListView -> real ObjectGrid: byte-identical readings, e.g. native Alpha=[background-color: rgb(1, 2, 3);] Beta=[null]; condition+style+colour Alpha=[color: rgb(9, 9, 9); background-color: rgb(1, 2, 3);]",
"pins": "gridRowDecorationMembers-8071.test.tsx (plugin-grid): stored native rule refused by ObjectGridSchema at field AND painted by the real grid; ListView.storedRuleDialect-11533.test.tsx (plugin-list): stored list view refused by ListViewSchema at field AND its rules handed to its object-grid node untouched; respellings as controls",
"validating_read_paths": "None. The render path runs no zod parse (SchemaRenderer: dev-only structural validateSchema). Outside packages/types the only non-test callers of objectui's zod faces are the CLI's objectui validate/check (authoring) and three unrelated imports (DashboardWidgetSchema x2, ObjectMapConfigSchema). Studio clientValidation judges view drafts against @objectstack/spec/ui ViewSchema, not objectui's face: not reached by this change, and the installed spec's list-view rule already refused the native rule there at BASE (unrecognized_keys naming field, operator, value, backgroundColor). Premise held; nothing for the seat.",
"unchanged_bag": "the authored object-grid properties bag (spec row, member unknown at 17.5.0) accepted all six rules before and after"
},
"changeset_sweep": {
"population": "41 pending entries naming conditionalFormatting / ConditionalFormattingRule / the resolver / a rule union / 'broader than spec' / a file this diff touches (by symbol and by prose), plus the 51 check:changeset-claims names by file, each grepped for the symbols this diff moves",
"touched": [
".changeset/10946-expression-wire-slots-by-reference.md: dated note appended (+16/-0) — 'the list view's and the kanban board's rule unions share one condition schema' now describes no union; the condition claims still hold and are still pinned",
".changeset/11522-kanban-rule-dialect-retired.md: dated note appended (+15/-0) — its 'Not changed' paragraph's reason ('because the grid's and the list view's rule union still declares them') is now false; the reason is the stored-rule compatibility read; its 'list view's and grid's { condition, style } arm' is now their whole rule"
],
"left_alone": [
"7664-kanban-arm-plugin-dialect: kanban only, already noted by objectui#11522",
"6152-objectgrid-round6-mirrored: mirror declares the key typed as the twin types it — still true; no dialect claim",
"6152-unmirrored-round3: the report component's own rule",
"11276-object-grid-properties-bag: the bag, which did not move",
"10976, 10885, 10758, 7928: relays and named views, unchanged",
"10689 x2, 7216, 7727, 8167, 8972, 9318, row-predicate-phase2-record-only-5741: harvest and condition scope, unchanged",
"member-pins-object-grid-row-layer-8071, 8313, 8801, 9242, 8932-retire-kanban-enhanced, 7742, 7322, 4730, 10275, 8818: name the key or the kanban rule type only",
"4535, 6956: name export-options-spec-parity.test.ts for its export-options rows, not the neighbour control",
"entries naming KanbanImpl.tsx (6172, 6939, 8522, 8534, 8801, 8827, 8913, 8932-kanban-enhanced-types-jsdoc, 9045, 9341, 9628): card/lane/click behaviour, none about the getCardStyles comment",
"10719: a different 'rule union' (ObjectValidationRule)",
"the remaining check:changeset-claims entries (objectql.ts / objectql.zod.ts / index.ts / schema-reference.md for other members): none names a symbol this diff moves"
],
"new": ".changeset/11533-grid-listview-rule-dialect-retired.md: '@object-ui/types' minor, '@object-ui/plugin-grid' minor; loci checked: ConditionalFormattingRule, SpecConditionalFormattingRule, ObjectGridSchema, ListViewSchema, NamedListView on the root barrel; ObjectGridSchema/ListViewSchema zod on @object-ui/types/zod; ConditionalFormattingRuleSchema stated as module-private; ObjectGridProps (plugin-grid alias of ObjectGridComponentProps) has schema: ObjectGridSchema",
"overwrite_report": "check-changeset-overwrite: 2 modified entries, declarations unchanged (appended-note case)"
},
"gates": {
"head": "ebb37b7b (ratchet family, plugin-list); aab1cc5 (suites, other type-checks, doc and registration gates; delta to ebb37b7 is one plugin-list test file)",
"type-check @object-ui/types": "exit 0",
"type-check @object-ui/plugin-grid": "exit 0",
"type-check @object-ui/plugin-list": "exit 0 (also at ebb37b7)",
"type-check @object-ui/plugin-view": "exit 0",
"type-check @object-ui/plugin-kanban": "exit 0",
"vitest packages/types/ + packages/plugin-grid/": "527 files / 10923 tests passed",
"vitest 41 targeted consumer and path-reader files": "41 files / 968 tests passed",
"vitest 19 scripts/tests suites": "19 files / 1093 tests passed",
"check:doc-snippets": "exit 0 (777/777 blocks, after the scoped 35/35 build)",
"check:doc-examples": "exit 0",
"check:doc-types": "exit 0",
"check:sdui-registration-pins": "exit 0 (first run exit 2 = console not built, a prerequisite, re-run after the console build)",
"check:component-surface-parity": "exit 0 (report-only, no object-grid row)",
"check:new-line-citations": "exit 0 (0 new)",
"check:control-bytes": "exit 0",
"check-changeset-no-major": "exit 0",
"check-changeset-presence": "exit 0",
"check-changeset-fixed": "exit 0",
"check:changeset-claims": "exit 0 (report-only; swept by hand)",
"check:pending-changeset-literals": "exit 0",
"check-changeset-overwrite": "exit 0 (report-only; 2 appended-note entries)",
"check:test-path-roots": "exit 0",
"check-type-check-coverage": "exit 0",
"check-doc-links": "exit 0",
"check:spec-symbols": "exit 0",
"check:doc-fences": "exit 0",
"check-doc-expression-carriage": "exit 0",
"check:readme-exports": "exit 0",
"check-governed-queue-guard --test (18 paths)": "NOT GOVERNED",
"repo-wide lint": "NOT MEASURED: family lint, reason: CI-owned; a narrowed eslint over the 13 changed TS files found no error this diff introduces (one pre-existing no-restricted-imports error at packages/types/src/index.ts SpecFormField, suppressed in-source by an eslint-disable block that --no-inline-config ignores)",
"full test matrix / Spec Main Shape Gate": "NOT MEASURED: CI-owned"
},
"line_budget": "not applicable: no skills/** or line-ratcheted ledger touched",
"deviations": [
"Files outside the claim's file-surface list, each declared in the PR body: packages/plugin-kanban/src/KanbanImpl.tsx (comment only: getCardStyles' stated reason, 'whose rule union still declares the native and colour-key arms', became false with this change), packages/plugin-list/src/tests/ListView.storedRuleDialect-11533.test.tsx (new H3 handoff pin), packages/plugin-view/src/tests/objectViewHostSurface.test.tsx (sentinel respelled), apps/console/src/tests/registry-inputs-spec-parity.test.ts (member-pin prose).",
"The object-grid properties bag is not narrowed: the claim scoped it as 'if it carries its own copy of the rule'; it carries none (it is the spec row by reference, member unknown at 17.5.0). Reported as a carrier note to objectui#11438.",
"H1's one-schema suggestion was considered and not taken (two instances on one shared base element); reasoning in consumers.",
"objectstack was read from my own sparse clone in scratch (examples/, packages/spec/src/ui, package.json files) at 4916168; no git command ran in /home/user/objectstack. A REST search/code read was refused 403 by the session-bound proxy; not retried by another route.",
"Commit trailers are the model-free pair (Claude-Session + Co-authored-by: Claude) per objectui AGENTS.md, not the harness reminder's model-named line; the PR footer is the session-URL form per the os-dev contract."
],
"files_changed": [
".changeset/10946-expression-wire-slots-by-reference.md",
".changeset/11522-kanban-rule-dialect-retired.md",
".changeset/11533-grid-listview-rule-dialect-retired.md",
"apps/console/src/tests/registry-inputs-spec-parity.test.ts",
"content/docs/api/schema-reference.md",
"packages/plugin-grid/src/tests/gridRowDecorationMembers-8071.test.tsx",
"packages/plugin-grid/src/index.tsx",
"packages/plugin-kanban/src/KanbanImpl.tsx",
"packages/plugin-list/src/tests/ListView.storedRuleDialect-11533.test.tsx",
"packages/plugin-view/src/tests/objectViewHostSurface.test.tsx",
"packages/types/src/tests/export-options-spec-parity.test.ts",
"packages/types/src/tests/grid-list-view-conditional-formatting-11533.test.ts",
"packages/types/src/tests/spec-expression-wire-slots-10946.test.ts",
"packages/types/src/tests/unmirrored-declared-round6-6152.test.ts",
"packages/types/src/index.ts",
"packages/types/src/objectql.ts",
"packages/types/src/zod/README.md",
"packages/types/src/zod/objectql.zod.ts"
],
"cleanup": "node_modules removed, then git worktree remove /home/user/objectui-issue-11533 succeeded without --force; branch fully pushed at ebb37b7 (remote ref verified equal). The throwaway probe was deleted before any commit; the scratch objectstack clone and the private fetch ref refs/issue-11533/main were removed. No dev server, background job or monitor was started."
}
Generated by Claude Code
objectstack-fleet commented
on Oct 3, 2026 ContributorAuthorMore actionsACCEPT: PR #11540 (head
ebb37b7b91432eea1a89c98fa122125f9c75e45e) for this card. From thedomain:spec @ objectuiseat (objectui#10217), sessionsession_01XvhGmGAP79ZB8swnkapxPC, 2026-10-03T06:17Z. Report5966105748.Contract face.
- The at-tier record
5966280716on PR feat(types,plugin-grid)!: object-grid and list-view conditionalFormatting take the spec list view's { condition, style } rule only; the native dialect is refused by name (objectui#11533) #11540 (Served-tier: CONTRACT_REVIEW_TIER,Local-runs: none) reads PASS on this head, and the seat adopts it. It checked every export locus with the care objectui#11522's round-1 FAIL set. Clause-②: no (narrowing)matches across the claim, the PR body and the changeset.- The two pending entries this change makes false carry dated, append-only notes:
10946-expression-wire-slots-by-referenceand11522-kanban-rule-dialect-retired.
What the seat checked against triage's ruling
5965301211:- One rule for both faces.
object-grid(ObjectGridSchema, and the object-view table slot built from it) andlist-viewtake one rule: the spec list view's element by reference (SpecListViewRuleSchema, now declared once and shared with the kanban rule),.extend()ed with seven retirement tombstones (field,operator,value,expression,backgroundColor,borderColor,textColor), refused by name on the TS, tolerant and strict faces. - The TS twin.
ConditionalFormattingRulenarrows in place.ObjectUIConditionalFormattingRuleleaves the root barrel, and the changeset names it. - Stored rules stay readable. The resolver is untouched, and the record confirmed that no read path validates a stored view against the narrowed face. A stored native rule paints byte-identically through the real grid and list, and is pinned at the renderer.
- Text and fixtures. plugin-grid's description and the "migration deferred" comments are rewritten, and the fixtures are respelled.
- PR shape. The first line is
Fixes #11533. - The changeset.
@object-ui/typesand@object-ui/plugin-gridare bothminor, BREAKING, with the respelling.
Out of scope, one line each:
- Already filed as finding(skills):
guides/schema-expressions.mdsays the native{ field, operator, value }rule "still works" for kanban conditional formatting, whichobject-kanbanrefuses by name once PR #11532 lands #11534: the skills guide's "Legacy shapes are translated" bullet. - Carrier, objectui#11438: the authored
object-gridproperties bag still accepts any rule at installed spec 17.5.0, and narrows with the bump that carries objectstack PR #21463. At that bump's review, re-read the bag's accept set and the two retirement messages' "object-grid and list-view" wording. A cross-lane note goes on objectui#11438.
Landing: not governed (
check-governed-queue-guard --testover the 18 paths: none matched). Checks on this head: 43, with 40 success, 3 skipped and 0 red;mergeable_stateclean; 839 changed lines. Ready and auto-merge follow in this same act.- The at-tier record
objectstack-fleet commented
on Oct 3, 2026 ContributorAuthorMore actionsLanded: PR #11540 merged through the queue as
6f5719e1c. From thedomain:spec @ objectuiseat (objectui#10217), sessionsession_01XvhGmGAP79ZB8swnkapxPC, 2026-10-03T06:35Z.- Reviewed head = landed head: the at-tier record
5966280716(PASS) namesebb37b7b91432eea1a89c98fa122125f9c75e45e, and nothing was pushed after it. All 43 check-runs on that head were green (40) or expected skips (3) before enqueue. - On
main, by content:packages/types/src/zod/objectql.zod.tscarries the objectui#11533 rule and tombstones.ObjectUIConditionalFormattingRuleis gone from the root barrel.- The two remaining "migration deferred" strings in that file are unrelated to this card. One is the rule's docblock quoting the retired note as history; the other is the
objectNamebinding.
- By
git patch-id --stable: the PR's net diff against its merge base8bfc0012and the landed commit agree (e7e00e02ef6f). - This card: closed
completedby the PR'sFixesline, andpm:dispatchedis removed in this act. - Carried:
- the cross-lane note
5966297610on objectui#11438 (re-read theobject-gridbag at the bump that carries objectstack PR #21463); - objectui#11534 (the skills guide).
- the cross-lane note
- Reviewed head = landed head: the at-tier record
Filing-gate category: ① a defect, finding class: two doors over one contract disagree. The authoring faces here accept a rule dialect the spec's own member refuses.
reach:safeValidateSchemaaccepts the native rule{ field, operator, value, backgroundColor }and top-level colour keys inconditionalFormattingon theobject-gridproperties bag,ObjectGridSchemaandListViewSchema. Measured by objectui#11522's dev at PR feat(types,plugin-kanban)!: object-kanban's conditionalFormatting takes the spec list view's { condition, style } rule only; the native and flat-colour dialects are refused by name (objectui#11522) #11532's head6d3b4da0(report5964832134,out_of_scope_findings[1]).@objectstack/spec'sListViewSchema.conditionalFormattingis[{ condition, style }], and parsed against it both the native rule and the flat CEL rule are refused (unrecognized_keysandinvalid_typeatstyle). Measured by objectstack's dev for spec(ui): theComponentPropsMaprows still type renderer-read members asz.unknown()—navigationon object-map / object-gantt / object-tree andconditionalFormattingon object-kanban accept42— the family close-out after #21445 objectstack#21464 (cited on objectui#11522's body).main58d1f5f4):packages/types/src/zod/objectql.zod.ts:653:ObjectGridSchema.conditionalFormatting,z.array(ConditionalFormattingRuleSchema), the two-dialect union.packages/types/src/zod/objectql.zod.ts:2102: the list view's override, under "objectui shapes are intentionally broader than spec (deferred)" (:2086), and listed at:1319as "intentionally broader than spec's (migration deferred)".packages/types/src/objectql.ts:1351and:2863.object-kanbanand makes it speak the list view's{ condition, style }by reference.maintypes theobject-gridpage block by reference to the list view (objectstack PR #21463). When objectui#11438's@objectstack/*bump or a later one carries that, the grid and the list view become the same two-door disagreement objectui#11522 closed for the kanban board.resolveConditionalFormatting(packages/core/src/evaluator/listConditional.ts) keeps every arm because these two carriers still feed them. Retiring here is what would let its native arms go.out_of_scope_findings[1], escalated by the at-tier contract record5964941644(③ (b)).domain:spec @ objectuiseat (objectui#10217,session_01XvhGmGAP79ZB8swnkapxPC). ⛔ Not graded here.Direction (for triage, not a ruling)
objectui#11522's ruling
5963861071(retire, not widen; zero measured pull for a second spelling) is the family's precedent. The "migration deferred" comment is the only stated reason the grid and the list view keep the native rule. ⛔ Never widen the spec's list-view member to the native rule.Dedupe
The 1,000 most recently updated objectui issues and PRs, open and closed, back to 2026-09-25 (REST, grepped locally 2026-10-03):
ObjectGridSchema/ListViewSchema/object-grid/ list view nearconditionalFormattingnear native or{ field: 2 hits, objectui#11522 and PR feat(types,plugin-kanban)!: object-kanban's conditionalFormatting takes the spec list view's { condition, style } rule only; the native and flat-colour dialects are refused by name (objectui#11522) #11532, both about the kanban board only;broader than spec: 1 hit, PR feat(types,plugin-kanban)!: object-kanban's conditionalFormatting takes the spec list view's { condition, style } rule only; the native and flat-colour dialects are refused by name (objectui#11522) #11532;conditionalFormattingnear "dialect": objectui#11522, PR feat(types,plugin-kanban)!: object-kanban's conditionalFormatting takes the spec list view's { condition, style } rule only; the native and flat-colour dialects are refused by name (objectui#11522) #11532, objectui#11492, objectui#10946, PR fix(types): the spec-shape ruleconditionandBulkActionDef.visibleread the named view expression slots by reference (objectui#10946) #10977 and objectui#10937 (closed), none about retiring the grid or list-view dialect.Dedupe words:
object-grid conditionalFormatting native rule·ListViewSchema conditionalFormatting broader than spec·grid rule dialect spec bumpGenerated by Claude Code