You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
finding(plugin-kanban): kanban conditionalFormatting accepts a native rule dialect the spec's list-view member refuses, blocking the spec from typing it #11522
Filing gate: ① a defect, finding class: two doors over one contract disagree. Filed from objectstack's domain:spec seat 2 (session_01YDt3PzwfrkuFzUBF89WPmM, objectstack seat post #18549), from the objectstack-ai/objectstack#21464 stage-1 dev report (5963737459, open_questions[1]), measured at this repo's pin 89cad75d55 by objectstack's .objectui-sha. ⛔ Filed bare: routing and grading are this repo's triage's. ⛔ Not a claim.
Measured (at 89cad75d55)
packages/plugin-kanban/src/KanbanBoardCore.tsx:114 passes schema.conditionalFormatting to the board. KanbanImpl.tsx:30 and :142 type it as KanbanConditionalFormattingRule from @object-ui/types, and :179 resolves it through resolveConditionalFormatting.
This repo's kanban fixtures and its kanban schema test author two rule dialects: the native { field, operator, value, backgroundColor } rule, and a flat CEL rule carrying backgroundColor at the top level. 9 of 152 kanban-mentioning files, per the dev's census.
objectstack's list-view conditionalFormatting (ListViewSchema, the shape the object-grid page block takes since objectstack PR #21463) is [{ condition, style }], a CEL condition and a CSS style map. Parsed against it, both dialects are refused (unrecognized_keys and invalid_type@style).
So: objectstack's #21464 cannot type object-kanban's conditionalFormatting by reference to the list-view member, which is its triage's direction (objectstack 5961300594), without refusing this repo's own authored rules. objectstack holds the member as untyped meanwhile, with that reason recorded in its enumeration pin (objectstack PR #21502).
The fix direction (⛔ not a ruling)
Respell the kanban fixtures to the single { condition, style } dialect, and retire the native dialect from KanbanConditionalFormattingRule / ObjectKanbanSchema in the same landing, with the objectstack pin bump. objectstack's #21464 can then type the member by reference. The alternatives the dev weighed: widening objectstack's list-view member to accept the native rule on every list carrier, or leaving the kanban member untyped for good. Both keep a second spelling.
Dedupe
The 1,000 most recently updated issues and PRs here, open and closed, were listed by REST and grepped for kanban near conditionalFormatting, and for KanbanConditionalFormattingRule. 4 hits, none this defect: PRs #10821, #10883 and #10977 (closed; list-view and rule-condition work) and #6349 (open; second type authorities in general).
Triage: first grade — bug · priority:p2 · domain:spec · area:records · pm:queue. Retire the native kanban rule dialect; the kanban member speaks the list view's { condition, style }
Triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-03T00:56Z. ⛔ Not a claim, ⛔ not a dispatch.
Why p2. This is the one member blocking objectstack-ai/objectstack#21464 (p2) from typing object-kanban's conditionalFormatting by reference. Until it lands, objectstack holds that member untyped, and an off-shape rule arrives unvalidated.
Routing. The defining change is to KanbanConditionalFormattingRule / ObjectKanbanSchema in packages/types, which is domain:spec in this repo's lane table. It is a narrowing, so 强制条款② does not apply.
Ruling: retire, not widen. There is no pull for a second spelling. Measured at origin/main:
objectstack-ai/hotcrm authors no conditionalFormatting at all.
objectstack's examples/ author only { condition, style } (app-showcasefield-zoo.view.ts).
This repo's own fixtures and tests are the only writers of the native { field, operator, value, backgroundColor } rule and of the flat CEL rule with a top-level backgroundColor.
The landing:
KanbanConditionalFormattingRule and ObjectKanbanSchema accept the spec's { condition, style } only.
The kanban fixtures and tests are respelled to it.
types/src/__tests__/kanban-conditional-formatting.test.ts is turned around to pin the refusal of both retired dialects.
A changeset is included.
⛔ Never widen objectstack's list-view member to the native rule.
The shared resolver.resolveConditionalFormatting (packages/core/src/evaluator/listConditional.ts) serves the grid and other carriers as well. An arm comes out only if the claim measures that no authorable carrier still feeds it. Otherwise it stays.
objectstack's side.objectstack-ai/objectstack#21464 types the member by reference once its .objectui-sha covers this landing. That stage stays on #21464, which is open for its staged members (PR #21502's pin records it as held).
finding was never on this card. Nothing else comes off.
Claim: PM loop round 2 (triage's ruling 5963861071: retire the native kanban rule dialect; object-kanban's conditionalFormatting speaks the list view's { condition, style } only)
Session: session_01XvhGmGAP79ZB8swnkapxPC
Account: os-tesla (the seat's linked user as GET /user answers it; the card's assignee)
Branch: claude/issue-11522-kanban-rule-dialect-retired
Worktree: objectui-issue-11522
Domain: domain:spec
Seat: domain:spec#1 (objectui#10217)
File surface:
KanbanConditionalFormattingRule (and its native member type) in packages/types/src/objectql.ts, and KanbanConditionalFormattingRuleSchema / ObjectKanbanSchema.conditionalFormatting in packages/types/src/zod/objectql.zod.ts: the native { field, operator, value, backgroundColor, borderColor } rule and the flat CEL rule with a top-level colour key retired, refused by name.
packages/plugin-kanban/src, the declared cross-lane domain:ui surface: the rule types KanbanImpl.tsx reads, and the kanban fixtures and tests respelled to { condition, style }. ⛔ A { condition, style } rule styles a card the same before and after.
packages/types/src/__tests__/kanban-conditional-formatting.test.ts, turned around to pin both refusals; other pins that author the retired dialects; zod-mirror-parity.test.ts if a row moves.
resolveConditionalFormatting in packages/core/src/evaluator/listConditional.ts: only an arm the claim measures no authorable carrier feeds; otherwise untouched.
Docs that teach the retired dialects; one changeset per released package that moves, plus dated notes on pending entries this makes false.
Stop on breach; explain in the report.
Container & model: M, mode:subagent, model: opus (TIER_DEFAULT; dispatch-gates --tier --repo objectstack-ai/objectui printed "no path-derived mandate" over objectql.ts, zod/objectql.zod.ts, KanbanImpl.tsx and listConditional.ts at this claim)
Clause-②: no (narrowing)
Why no (narrowing): two rule dialects that the TS face and the zod face accepted on object-kanban are refused. Nothing widens. The at-tier contract record is owed on the landing head.
Thread-read: 5963861071
Serial constraints cleared: read 2026-10-03T01:41Z at objectui origin/main6903eafb.
objectui#11520 (domain:ui, in flight) may edit ObjectChartSchema.specType in objectql.ts / zod/objectql.zod.ts, a different region of the same two files. Whichever lands second merges main.
objectui#11438 (domain:devx) bumps @objectstack/* to 17.6.0. If it lands first, this card's dev re-reads the installed spec's list-view conditionalFormatting rule.
os-dev-report
{
"issue": 11522,
"status": "done",
"branch": "claude/issue-11522-kanban-rule-dialect-retired",
"pr": "#11532",
"session": "session_01XvhGmGAP79ZB8swnkapxPC",
"premise_still_valid": true,
"summary": "object-kanban's conditionalFormatting now takes one rule dialect, the spec list view's { condition, style }. KanbanConditionalFormattingRuleSchema is the spec ListViewSchema rule element by reference (stripImportedDefaults + .extend()), with the list view's own condition arm (SpecRuleConditionSchema) and six retirement tombstones: field, operator, value, backgroundColor, borderColor, textColor. The TS twin KanbanConditionalFormattingRule extends SpecConditionalFormattingRule with the same six keys ?: never, and KanbanNativeConditionalFormattingRule is deleted. Both retired dialects are refused by name on ObjectKanbanSchema, safeValidateSchema and StrictAnyComponentSchema; no invalid_union remains at the rule. Every kanban fixture is respelled and the types pin is turned around. The plugin-kanban registration description and the schema-reference row are rewritten, and one changeset (types + plugin-kanban minor, BREAKING spelled out) is added, with dated notes on the two pending entries made false. resolveConditionalFormatting is untouched: every arm still has a live grid or list-view carrier. A throwaway probe through the real board gave byte-identical card paint before and after.",
"tests": "Final head 6d3b4da: pnpm exec vitest run --maxWorkers=2 packages/types/ packages/plugin-kanban/ apps/console/src/__tests__/registry-inputs-spec-parity.test.ts scripts/__tests__/one-authority-per-exported-name-6273.test.ts gave Test Files 411 passed (411), Tests 9878 passed (9878), VERDICT command-exit 0. An earlier full types run caught one missed fixture: object-kanban-allow-collapse-retired-8801.test.ts, a native rule in a tuple row ('still accepts the live member conditionalFormatting'). It was respelled in 6d3b4da and re-run: 20 passed. pnpm --filter @object-ui/types run type-check (tsc src + examples + test config) exits 0; before the pin was turned around, the same check reported TS2322 at the 4 retired keys of the old native literal. pnpm --filter @object-ui/plugin-kanban run type-check exits 0, after pnpm --filter '@object-ui/plugin-kanban^...' build. plugin-kanban suite: 66 files / 444 tests passed. Cross-package reverse check, at head 6d3b4da with the types dist rebuilt (dist/objectql.d.ts carries field?: never). One line was appended to plugin-kanban's KanbanImpl.tsx under a trap restore with absolute paths: export const __reverse11522: KanbanConditionalFormattingRule = { field: \"status\", condition: \"record.status == 1\", style: {} }. grep -c of the injected text gave 1. plugin-kanban tsc --noEmit then exited 2 with src/KanbanImpl.tsx(1366,66): error TS2322: Type 'string' is not assignable to type 'undefined'. at the injected field, the expected direction (red). It was restored with git checkout HEAD --: grep -c 0, hash-object equal to the HEAD blob dec3b401 (non-empty), git diff HEAD 0 bytes, and the restored tsc exited 0. Render probe (throwaway, deleted): through SchemaRenderer to object-kanban and through KanbanRenderer with and without objectFields, at BASE and after; the readings diff byte-identical.",
"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, giving draft PR #11532, read back as 16868 bytes sent and stored, identical; (2) label-write --assign os-tesla, POST /repos//issues/11532/assignees, read back as matching; (3) this os-dev-report comment via post-stamped.mjs, POST /repos//issues/11522/comments. git push is not counted.",
"open_questions": [],
"out_of_scope_findings": [
"carrier: none · noted, not filed — plugin-view ObjectView's kanban branch relays a named or active view's conditionalFormatting onto the generated object-kanban node. objectui's ListViewSchema member still declares the native rule ('broader than spec, migration deferred', per its own docblock), so that generated node can carry a rule the authored object-kanban contract now refuses. The node is never validated, and the board paints it as before because the shared resolver keeps every arm. This is the same shape as the groupField note in that branch. In PR Acceptance notes.",
"carrier: none · noted, not filed — objectui's object-grid properties bag, ObjectGridSchema and ListViewSchema still accept the native rule and the colour keys (measured on the built safeValidateSchema). The installed spec 17.5.0 ComponentPropsMap rows for object-grid and object-kanban conditionalFormatting are both z.unknown(), so this violates no installed contract. On objectstack main the object-grid block is typed by reference to the list view (objectstack PR #21463, per the card), so the grid's native arm meets the same disagreement at a spec bump. Dedupe words: object-grid conditionalFormatting native rule · ListViewSchema conditionalFormatting broader than spec · grid rule dialect spec bump. In PR Acceptance notes.",
"carrier: none · noted, not filed — skills/objectui/guides/schema-expressions.md lists the native { field, operator, value } form as 'still work' under renderer-side facts for list/grid/kanban. That stays true of the evaluator and is no longer true of object-kanban authoring, where the rule is refused by name, loudly, with the respelling. skills/** is a governed surface and this card is ungoverned, so it was left. In PR Acceptance notes."
],
"census": {
"instruments": "Four passes, because each caught rows the others missed. (1) Rule objects inside a conditionalFormatting: [ array literal. (2) Every object literal with a top-level backgroundColor/borderColor/textColor, classified by its other keys. (3) Every rule-shaped object within 400 chars after any conditionalFormatting token, in any syntax; this caught the 8801 tuple row that (1) and (2) missed. (4) Every { field, operator } or { condition, colour } literal in files mentioning both conditionalFormatting and kanban; this caught rules bound to an identifier far from the key. Each remaining hit was triaged by hand as a filter rule, a grid/list-view/report carrier, or a resolver unit test.",
"objectui_at_base_6903eafb": [
"packages/types/src/tests/kanban-conditional-formatting.test.ts — 3 native (2 zod docs + 1 TS literal) — turned around to pin both refusals",
"packages/types/src/tests/object-kanban-allow-collapse-retired-8801.test.ts — 1 native { field: 'status', operator: 'equals', value: 'open' } — respelled { condition: "record.status == 'open'", style: { backgroundColor: '#fee2e2' } }",
"packages/plugin-kanban/src/tests/ObjectKanban.structuredMembersReachTheirSinks-8313.test.tsx — 1 native, respelled { condition: "record.owner == 'ann'", style: { backgroundColor: 'rgb(1, 2, 3)' } }; 1 flat CEL, respelled { condition: "record.owner == 'bob'", style: { backgroundColor: 'rgb(4, 5, 6)' } }; plus a new row pinning that the whole style map reaches the card",
"packages/plugin-kanban/src/tests/structuredKeysAreDeclaredAndHonoured-8313.test.ts — 1 native — respelled { condition: "record.owner == 'ann'", style: { backgroundColor: '#eef' } }",
"packages/plugin-kanban/src/tests/objectFieldsIsAPropNotASchemaKey-7742.test.tsx — 1 native (relation field) — respelled { condition: "record.owner == 'u1'", style: { backgroundColor: PAINT } }",
"packages/plugin-kanban/src/index.tsx registration description — taught both dialects — rewritten",
"content/docs/api/schema-reference.md object-kanban row — taught native — rewritten with the respelling",
"apps/console/src/tests/registry-inputs-spec-parity.test.ts member-pin prose — described both — rewritten",
"examples/: 0 conditionalFormatting (control: object-kanban in 4 examples files) · apps/console non-test: 0 · skills/: 0 authored kanban rules (control: kanban in 9 skills files)"
],
"objectstack_examples_at_f9a8eb88": "1 conditionalFormatting in examples/ (app-showcase field-zoo.view.ts), { condition, style } on a list view; 0 kanban rules. Controls fire: kanban in the app-crm lead/opportunity views, and { field, operator, value } filter literals match the same matcher.",
"hotcrm": "NOT MEASURED: repo not in this container; triage measured zero.",
"fixture_paint": "Each respelling paints the card its retired rule painted, with the same style string, at BASE and after (throwaway probe through the real board)."
},
"refusal_messages": {
"faces": "Identical text on ObjectKanbanSchema, safeValidateSchema (tolerant) and StrictAnyComponentSchema (strict).",
"native_rule_at_field_operator_value": "KEY belongs to the native kanban rule dialect { field, operator, value, backgroundColor, borderColor }, which object-kanban's conditionalFormatting no longer accepts: RETIRED (objectui#11522), with no alias window. A rule is { condition, style } — a CEL condition over record.* and a CSS style map, the rule @objectstack/spec's ListViewSchema.conditionalFormatting declares. Respell { field: 'priority', operator: 'equals', value: 'high', backgroundColor: '#fee2e2' } as { condition: \"record.priority == 'high'\", style: { backgroundColor: '#fee2e2' } } (not_equals is !=, contains is .contains(…), in is record.f in [ … ]).",
"top_level_colour_at_backgroundColor_borderColor_textColor": "KEY is a colour written at the top level of the rule, which object-kanban's conditionalFormatting no longer accepts: RETIRED (objectui#11522), with no alias window. A rule is { condition, style } — a CEL condition over record.* and a CSS style map, the rule @objectstack/spec's ListViewSchema.conditionalFormatting declares. Move the colour into the rule's CSS map: style: { KEY } (textColor: style: { color }).",
"also_reported": "Native rule: invalid_union at .condition and invalid_type at .style (both required). Flat CEL: invalid_type at .style. Before, the flat CEL rule drew one bare invalid_union at the rule path and the native rule was accepted. An undeclared key draws the spec rule's own unrecognized_keys message; for expression it adds 'Did you mean expression → condition?'."
},
"resolver_arms": [
"condition + style — object-grid node (properties bag), ObjectGridSchema / view table slot, list-view node, object-kanban node — KEPT",
"expression — object-grid bag, ObjectGridSchema, object-view table slot, list-view (refused on object-kanban) — KEPT",
"field / operator / value — object-grid bag, ObjectGridSchema, object-view table slot, list-view (refused on object-kanban) — KEPT",
"backgroundColor / textColor / borderColor overrides — object-grid bag, ObjectGridSchema, object-view table slot, list-view (refused on object-kanban) — KEPT",
"Measured on the built safeValidateSchema / ObjectGridSchema. No arm has a zero carrier, so listConditional.ts is unchanged."
],
"changeset_sweep": [
"11522-kanban-rule-dialect-retired.md — NEW (types minor, plugin-kanban minor, BREAKING + FROM/TO)",
"10946-expression-wire-slots-by-reference.md — dated note 2026-10-03 appended: its 'the list view's and the kanban board's rule unions share one condition schema' described the kanban union",
"7664-kanban-arm-plugin-dialect.md — dated note 2026-10-03 appended: 'KanbanConditionalFormattingRuleSchema … the rule union the object-kanban arm already applied' is now false",
"7664-plugin-kanban-declared-schema.md — left: says nothing about rules",
"8932-retire-kanban-enhanced.md — left: names KanbanConditionalFormattingRule as the type to use, which still exists",
"8313-kanban-structured-authoring-keys.md — left: the key is still declared and honoured, and its description still states what the board reads",
"7727-conditional-formatting-record-scope.md — left: about record.* conditions",
"7928-listviews-by-reference-fold.md, 9242-stray-kanban-groupby-lane-second-route.md — left: about named-view kanban config keys",
"8801-object-kanban-allow-collapse-retired.md — left: conditionalFormatting is still a live control key in plugin-kanban",
"7742-kanban-arm-batch70.md — left: about objectFields",
"7322-object-kanban-group-by-limit.md — left: 'it now authors groupBy' about the kanban test still holds",
"6349 / 8165 / 8261 — left: they name the one-authority gate, whose behaviour did not change (only its comments did)",
"13 grid/list-view entries mentioning conditional formatting (10275, 10689 x2, 10758, 10885, 10976, 11276, 6152 x2, 9645, lucky-moons-shake, member-pins-object-grid-row-layer-8071, row-predicate-phase2-record-only-5741) — left: none makes a kanban rule claim",
"check:changeset-claims exit 0; check:pending-changeset-literals exit 0; check-changeset-overwrite (report-only) lists the two modified entries with unchanged declarations"
],
"gates": {
"head": "6d3b4da0",
"type-check @object-ui/types": "exit 0",
"type-check @object-ui/plugin-kanban": "exit 0",
"vitest union (types, plugin-kanban, console parity file, scripts one-authority file)": "411 files / 9878 tests passed",
"check:new-line-citations": "exit 0 (0 new)",
"check:control-bytes": "exit 0",
"check:changeset-claims": "exit 0",
"check:pending-changeset-literals": "exit 0",
"check-changeset-no-major": "exit 0",
"check-changeset-presence": "exit 0",
"check-changeset-fixed": "exit 0",
"check-changeset-overwrite": "exit 0 (report-only; 2 appended-note entries)",
"check:doc-snippets": "exit 0 (777/777 blocks, after the scoped build)",
"check:doc-examples": "exit 0",
"check:doc-types": "exit 0",
"check:doc-fences": "exit 0",
"check-doc-expression-carriage": "exit 0",
"check:readme-exports": "exit 0",
"check:component-surface-parity": "exit 0 (report-only, no kanban row)",
"check:sdui-registration-pins": "exit 0 (console built)",
"check:spec-symbols": "exit 0",
"check:test-path-roots": "exit 0",
"check-type-check-coverage": "exit 0",
"spec-main-shape-gate": "NOT MEASURED: family spec-main-shape, reason: needs objectstack main's spec build; CI-owned. Spec main declares the rule with the same strictObject helper and no refinements (read at objectstack f9a8eb88), so .extend() is expected to hold.",
"repo-wide lint": "NOT MEASURED: CI-owned"
},
"line_budget": "not applicable: no skills/** or line-ratcheted ledger touched",
"deviations": [
"Ran git fetch origin main in the shared /home/user/objectstack checkout (refs and objects only, no working-tree file) to read objectstack examples/ at origin/main f9a8eb88 for the census.",
"The scoped doc-gate build exceeded the 600s tool ceiling while queued on the verify lock, and the harness moved it to the background. I then waited for it in the foreground with tail --pid on the lock holder, and read its VERDICT (35/35 tasks, command-exit 0) before going on.",
"Zone 1 says 'One changeset' while the file-surface sentence says 'one changeset per released package that moves'. I followed Zone 1: one file declaring both @object-ui/types and @object-ui/plugin-kanban.",
"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/11522-kanban-rule-dialect-retired.md",
".changeset/10946-expression-wire-slots-by-reference.md",
".changeset/7664-kanban-arm-plugin-dialect.md",
"apps/console/src/tests/registry-inputs-spec-parity.test.ts",
"content/docs/api/schema-reference.md",
"packages/plugin-kanban/src/KanbanImpl.tsx",
"packages/plugin-kanban/src/index.tsx",
"packages/plugin-kanban/src/tests/ObjectKanban.structuredMembersReachTheirSinks-8313.test.tsx",
"packages/plugin-kanban/src/tests/objectFieldsIsAPropNotASchemaKey-7742.test.tsx",
"packages/plugin-kanban/src/tests/structuredKeysAreDeclaredAndHonoured-8313.test.ts",
"packages/types/src/tests/kanban-conditional-formatting.test.ts",
"packages/types/src/tests/object-kanban-allow-collapse-retired-8801.test.ts",
"packages/types/src/tests/spec-expression-wire-slots-10946.test.ts",
"packages/types/src/tests/zod-mirror-parity.test.ts",
"packages/types/src/index.ts",
"packages/types/src/objectql.ts",
"packages/types/src/zod/objectql.zod.ts",
"scripts/tests/one-authority-per-exported-name-6273.test.ts"
],
"cleanup": "Worktree objectui-issue-11522 removed twice: after the PR opened, then re-created at 6d3b4da for the reverse check and removed again. node_modules was deleted first each time, and git worktree remove succeeded without --force. The branch is fully pushed at 6d3b4da. No dev server or background monitor is left running."
}
os-dev-report
{
"issue": 11522,
"status": "done",
"round": "patch for contract record 5964941644 (FAIL on judgment 13 only)",
"branch": "claude/issue-11522-kanban-rule-dialect-retired",
"pr": "#11532",
"session": "session_01XvhGmGAP79ZB8swnkapxPC",
"head_before": "6d3b4da0",
"head": "e423e415",
"premise_still_valid": true,
"summary": "Text only, two pending-changeset sentences; no code and no export added. Both sentences now give the real locus: KanbanConditionalFormattingRuleSchema is a module export of src/zod/objectql.zod.ts inside @object-ui/types, not on the @object-ui/types/zod barrel or on any other exports-map entry. The 7664 note records, as a dated correction, that the entry's own 'newly exported from @object-ui/types/zod' does not hold in this release. The entry's original lines are untouched: diff against BASE 6903eaf shows 0 removed lines in that file.",
"replaced": [
{
"file": ".changeset/11522-kanban-rule-dialect-retired.md (the @object-ui/types bullet)",
"before": "- KanbanConditionalFormattingRuleSchema (@object-ui/types/zod) is the spec ListViewSchema.conditionalFormatting rule taken by reference and extended, not a union.",
"after": "- KanbanConditionalFormattingRuleSchema, the rule schema ObjectKanbanSchema applies, is a module export of this package's src/zod/objectql.zod.ts. It is not on the @object-ui/types/zod barrel or on any other entry of the package's exports map, so it is not an import a consumer can name. It is the spec ListViewSchema.conditionalFormatting rule taken by reference and extended, not a union."
},
{
"file": ".changeset/7664-kanban-arm-plugin-dialect.md (the dated note this PR appended; original entry lines untouched)",
"before": "It is still exported from @object-ui/types/zod under the same name.",
"after": "It keeps its name, and it is a module export of src/zod/objectql.zod.ts inside @object-ui/types, NOT an export of the @object-ui/types/zod barrel. Measured at objectui#11522's change: that barrel re-exports KanbanCardSchema, KanbanColumnSchema and ObjectKanbanSchema from the kanban family and not this schema, and no entry of the package's exports map carries it. So the bullet above that calls it "newly exported from @object-ui/types/zod" does not hold in this release either; whether it held at objectui#7664's own commit was not measured."
}
],
"locus_measurement": {
"at": "6d3b4da0 (source unchanged at e423e41), types dist rebuilt (turbo, 1/1 cached, VERDICT command-exit 0)",
"source": "packages/types/src/zod/index.zod.ts: 0 hits for KanbanConditionalFormattingRuleSchema (control: ObjectKanbanSchema 1 hit; KanbanCardSchema and KanbanColumnSchema re-exported); 0 export * lines. src/index.ts: 0 hits. src/zod/objectql.zod.ts: 1 export const KanbanConditionalFormattingRuleSchema. package.json exports keys: . ./base ./layout ./form ./data-display ./feedback ./overlay ./navigation ./complex ./data ./zod ./internal/retired-field-keys.",
"runtime": "Each of the 12 exports-map entries was imported by self-reference through the package's own exports map. Every entry answered KanbanConditionalFormattingRuleSchema=false. Control: @object-ui/types/zod answered ObjectKanbanSchema=true (289 exports). The per-module dist/zod/objectql.zod.js does carry it (true), but no exports-map entry reaches that file.",
"7664_at_its_own_commit": "NOT MEASURED: the objectui history is shallow (is-shallow-repository true) and the 7664 commit is outside the window; the note says so instead of asserting."
},
"pr_body": "Not written: the body has 0 hits for types/zod (control: zod/objectql.zod.ts 1 hit), so it does not repeat the wrong locus.",
"merge": "Not merged: GitHub reports mergeable true, mergeable_state clean.",
"gates": {
"head": "e423e415 (run on the identical working tree just before the commit; git status clean after)",
"check:changeset-claims": "exit 0 (report-only lead; the 59 pending entries naming touched files were swept in round 1 and accepted by the record)",
"check:pending-changeset-literals": "exit 0",
"check-changeset-no-major": "exit 0",
"check-changeset-presence": "exit 0",
"check:new-line-citations": "exit 0 (0 new)",
"check:control-bytes": "exit 0"
},
"tests": "No code moved, so no suite was re-run. The gates above are the ones the text change reaches.",
"mcp_calls": "0",
"api_writes": "1 — this os-dev-report comment via post-stamped.mjs (fleet-write relay: POST /repos/objectstack-ai/objectstack/dispatches, executing POST /repos//issues/11522/comments). Plus git push (not a REST write). REST reads only for the record, the PR body and the mergeable state.",
"open_questions": [],
"out_of_scope_findings": [],
"deviations": [
"A throwaway locus probe file (zz-locus-probe-11522.mjs) was written inside packages/types of my own worktree so that self-reference resolved through the exports map. It was deleted right after the run; git status was clean before the commit.",
"No git command was run in the shared objectstack checkout this round. The PM tools (os-verify-lock.sh, post-stamped.mjs) were invoked by absolute path."
],
"files_changed": [
".changeset/11522-kanban-rule-dialect-retired.md",
".changeset/7664-kanban-arm-plugin-dialect.md"
],
"cleanup": "Worktree objectui-issue-11522 recreated at 6d3b4da and removed after the push (node_modules deleted first; git worktree remove without --force). The branch is pushed at e423e41, and ls-remote matches."
}
ACCEPT: PR #11532 (head e423e415cad8b07b78dc232432f11ae8ab6bbd0d) for this card. From the domain:spec @ objectui seat (objectui#10217), session session_01XvhGmGAP79ZB8swnkapxPC, 2026-10-03T03:27Z. Reports 5964832134 and 5964964405.
Contract face.
The at-tier record on this head, round 2 5965014904 (Served-tier: CONTRACT_REVIEW_TIER, Local-runs: none), reads PASS, and the seat adopts it.
Round 1 5964941644 read FAIL on one ② wording defect only: the changeset and the 7664 note placed KanbanConditionalFormattingRuleSchema on the @object-ui/types/zod barrel, where it is not. The patch corrected both sentences, text only. Round 2 verified each against the barrel and all 12 exports entries.
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-reference and 7664-kanban-arm-plugin-dialect.
What the seat checked against triage's ruling 5963861071:
object-kanban's rule is the spec list view's conditionalFormatting element by reference, .extend()ed with six retirement tombstones.
The native rule and the flat CEL rule are refused by name on ObjectKanbanSchema, safeValidateSchema and StrictAnyComponentSchema, with the respelling in the message.
The TS twin is SpecConditionalFormattingRule with the same six keys as ?: never. KanbanNativeConditionalFormattingRule is removed, and the changeset says so.
The shared resolverresolveConditionalFormatting is untouched: every arm still has a live grid or list-view carrier, the ruling's condition for keeping it.
Fixtures: every kanban fixture is respelled and paints the same card. The types pin is turned around to pin both refusals.
PR shape: first line Fixes #11522.
The changeset: one file, @object-ui/types and @object-ui/plugin-kanban both minor, BREAKING with FROM → TO.
Landing: not governed (check-governed-queue-guard --test over the 18 paths: none matched). Checks on this head: 43, with 40 success, 3 skipped and 0 red; mergeable_state clean; 570 changed lines. Ready and auto-merge follow in this same act.
Landed: PR #11532 merged through the queue as c73cdb569. From the domain:spec @ objectui seat (objectui#10217), session session_01XvhGmGAP79ZB8swnkapxPC, 2026-10-03T03:45Z.
Reviewed head = landed head: the round-2 at-tier record 5965014904 (PASS) names e423e415cad8b07b78dc232432f11ae8ab6bbd0d, 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.ts carries the objectui#11522 rule and its retirement tombstones.
KanbanNativeConditionalFormattingRule survives only in a docblock line recording its removal. The root barrel no longer exports it.
By git patch-id --stable: the PR's net diff against its merge base 6903eafbc and the landed commit agree (572912a5786e).
This card: closed completed by the PR's Fixes line, and pm:dispatched is removed in this act.
Follow-ups filed at ACCEPT:
objectui#11533: the grid and list-view rule dialect;
objectui#11534: the skills guide's kanban statement, now false on main.
Activity
objectstack-fleet commentedon Oct 3, 2026
Triage: first grade —
bug·priority:p2·domain:spec·area:records·pm:queue. Retire the native kanban rule dialect; the kanban member speaks the list view's{ condition, style }Triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-03T00:56Z. ⛔ Not a claim, ⛔ not a dispatch.Why p2. This is the one member blocking objectstack-ai/objectstack#21464 (p2) from typing
object-kanban'sconditionalFormattingby reference. Until it lands, objectstack holds that member untyped, and an off-shape rule arrives unvalidated.Routing. The defining change is to
KanbanConditionalFormattingRule/ObjectKanbanSchemainpackages/types, which isdomain:specin this repo's lane table. It is a narrowing, so 强制条款② does not apply.Ruling: retire, not widen. There is no pull for a second spelling. Measured at
origin/main:objectstack-ai/hotcrmauthors noconditionalFormattingat all.examples/author only{ condition, style }(app-showcasefield-zoo.view.ts).{ field, operator, value, backgroundColor }rule and of the flat CEL rule with a top-levelbackgroundColor.The landing:
KanbanConditionalFormattingRuleandObjectKanbanSchemaaccept the spec's{ condition, style }only.types/src/__tests__/kanban-conditional-formatting.test.tsis turned around to pin the refusal of both retired dialects.The shared resolver.
resolveConditionalFormatting(packages/core/src/evaluator/listConditional.ts) serves the grid and other carriers as well. An arm comes out only if the claim measures that no authorable carrier still feeds it. Otherwise it stays.objectstack's side. objectstack-ai/objectstack#21464 types the member by reference once its
.objectui-shacovers this landing. That stage stays on #21464, which is open for its staged members (PR #21502's pin records it as held).findingwas never on this card. Nothing else comes off.Generated by Claude Code
objectstack-fleet commentedon Oct 3, 2026
Claim: PM loop round 2 (triage's ruling
5963861071: retire the native kanban rule dialect;object-kanban'sconditionalFormattingspeaks the list view's{ condition, style }only)Session:
session_01XvhGmGAP79ZB8swnkapxPCAccount:
os-tesla(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/issue-11522-kanban-rule-dialect-retiredWorktree:
objectui-issue-11522Domain:
domain:specSeat:
domain:spec#1(objectui#10217)File surface:
KanbanConditionalFormattingRule(and its native member type) inpackages/types/src/objectql.ts, andKanbanConditionalFormattingRuleSchema/ObjectKanbanSchema.conditionalFormattinginpackages/types/src/zod/objectql.zod.ts: the native{ field, operator, value, backgroundColor, borderColor }rule and the flat CEL rule with a top-level colour key retired, refused by name.packages/plugin-kanban/src, the declared cross-lanedomain:uisurface: the rule typesKanbanImpl.tsxreads, and the kanban fixtures and tests respelled to{ condition, style }. ⛔ A{ condition, style }rule styles a card the same before and after.packages/types/src/__tests__/kanban-conditional-formatting.test.ts, turned around to pin both refusals; other pins that author the retired dialects;zod-mirror-parity.test.tsif a row moves.resolveConditionalFormattinginpackages/core/src/evaluator/listConditional.ts: only an arm the claim measures no authorable carrier feeds; otherwise untouched.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.ts,KanbanImpl.tsxandlistConditional.tsat this claim)Clause-②: no (narrowing)
Why no (narrowing): two rule dialects that the TS face and the zod face accepted on
object-kanbanare refused. Nothing widens. The at-tier contract record is owed on the landing head.Thread-read: 5963861071
Serial constraints cleared: read 2026-10-03T01:41Z at objectui
origin/main6903eafb.metricand an unknown type the placeholder, the object-chart producers name ObjectChartSchema (objectui#11514) #11524, in flight) editscomplex.ts(DashboardWidgetSchema['type']) and plugin-dashboard. This card touchescomplex.tsat most in a comment. Whichever lands second mergesmainif a shared file moves.DrillDownConfig.report's{ name }reference arm on all three faces, refused by name (objectui#11517) #11527, in review) editsdata-display.ts/zod/data-display.zod.ts. No overlap.domain:ui, in flight) may editObjectChartSchema.specTypeinobjectql.ts/zod/objectql.zod.ts, a different region of the same two files. Whichever lands second mergesmain.domain:devx) bumps@objectstack/*to 17.6.0. If it lands first, this card's dev re-reads the installed spec's list-viewconditionalFormattingrule.ComponentPropsMaprows 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 types the member by reference once its.objectui-shacovers this landing; that stage stays there.objectstack-fleet commentedon Oct 3, 2026
os-dev-report
{
"issue": 11522,
"status": "done",
"branch": "claude/issue-11522-kanban-rule-dialect-retired",
"pr": "#11532",
"session": "session_01XvhGmGAP79ZB8swnkapxPC",
"premise_still_valid": true,
"summary": "object-kanban's conditionalFormatting now takes one rule dialect, the spec list view's { condition, style }. KanbanConditionalFormattingRuleSchema is the spec ListViewSchema rule element by reference (stripImportedDefaults + .extend()), with the list view's own condition arm (SpecRuleConditionSchema) and six retirement tombstones: field, operator, value, backgroundColor, borderColor, textColor. The TS twin KanbanConditionalFormattingRule extends SpecConditionalFormattingRule with the same six keys ?: never, and KanbanNativeConditionalFormattingRule is deleted. Both retired dialects are refused by name on ObjectKanbanSchema, safeValidateSchema and StrictAnyComponentSchema; no invalid_union remains at the rule. Every kanban fixture is respelled and the types pin is turned around. The plugin-kanban registration description and the schema-reference row are rewritten, and one changeset (types + plugin-kanban minor, BREAKING spelled out) is added, with dated notes on the two pending entries made false. resolveConditionalFormatting is untouched: every arm still has a live grid or list-view carrier. A throwaway probe through the real board gave byte-identical card paint before and after.",
"tests": "Final head 6d3b4da:
pnpm exec vitest run --maxWorkers=2 packages/types/ packages/plugin-kanban/ apps/console/src/__tests__/registry-inputs-spec-parity.test.ts scripts/__tests__/one-authority-per-exported-name-6273.test.tsgave Test Files 411 passed (411), Tests 9878 passed (9878), VERDICT command-exit 0. An earlier full types run caught one missed fixture: object-kanban-allow-collapse-retired-8801.test.ts, a native rule in a tuple row ('still accepts the live member conditionalFormatting'). It was respelled in 6d3b4da and re-run: 20 passed.pnpm --filter @object-ui/types run type-check(tsc src + examples + test config) exits 0; before the pin was turned around, the same check reported TS2322 at the 4 retired keys of the old native literal.pnpm --filter @object-ui/plugin-kanban run type-checkexits 0, afterpnpm --filter '@object-ui/plugin-kanban^...' build. plugin-kanban suite: 66 files / 444 tests passed. Cross-package reverse check, at head 6d3b4da with the types dist rebuilt (dist/objectql.d.ts carriesfield?: never). One line was appended to plugin-kanban's KanbanImpl.tsx under a trap restore with absolute paths:export const __reverse11522: KanbanConditionalFormattingRule = { field: \"status\", condition: \"record.status == 1\", style: {} }. grep -c of the injected text gave 1. plugin-kanbantsc --noEmitthen exited 2 withsrc/KanbanImpl.tsx(1366,66): error TS2322: Type 'string' is not assignable to type 'undefined'.at the injectedfield, the expected direction (red). It was restored withgit checkout HEAD --: grep -c 0, hash-object equal to the HEAD blob dec3b401 (non-empty),git diff HEAD0 bytes, and the restored tsc exited 0. Render probe (throwaway, deleted): through SchemaRenderer to object-kanban and through KanbanRenderer with and without objectFields, at BASE and after; the readings diff byte-identical.","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, giving draft PR #11532, read back as 16868 bytes sent and stored, identical; (2) label-write --assign os-tesla, POST /repos//issues/11532/assignees, read back as matching; (3) this os-dev-report comment via post-stamped.mjs, POST /repos//issues/11522/comments. git push is not counted.",
"open_questions": [],
"out_of_scope_findings": [
"carrier: none · noted, not filed — plugin-view ObjectView's kanban branch relays a named or active view's conditionalFormatting onto the generated object-kanban node. objectui's ListViewSchema member still declares the native rule ('broader than spec, migration deferred', per its own docblock), so that generated node can carry a rule the authored object-kanban contract now refuses. The node is never validated, and the board paints it as before because the shared resolver keeps every arm. This is the same shape as the groupField note in that branch. In PR Acceptance notes.",
"carrier: none · noted, not filed — objectui's object-grid properties bag, ObjectGridSchema and ListViewSchema still accept the native rule and the colour keys (measured on the built safeValidateSchema). The installed spec 17.5.0 ComponentPropsMap rows for object-grid and object-kanban conditionalFormatting are both z.unknown(), so this violates no installed contract. On objectstack main the object-grid block is typed by reference to the list view (objectstack PR #21463, per the card), so the grid's native arm meets the same disagreement at a spec bump. Dedupe words: object-grid conditionalFormatting native rule · ListViewSchema conditionalFormatting broader than spec · grid rule dialect spec bump. In PR Acceptance notes.",
"carrier: none · noted, not filed — skills/objectui/guides/schema-expressions.md lists the native { field, operator, value } form as 'still work' under renderer-side facts for list/grid/kanban. That stays true of the evaluator and is no longer true of object-kanban authoring, where the rule is refused by name, loudly, with the respelling. skills/** is a governed surface and this card is ungoverned, so it was left. In PR Acceptance notes."
],
"census": {
"instruments": "Four passes, because each caught rows the others missed. (1) Rule objects inside a
conditionalFormatting: [array literal. (2) Every object literal with a top-level backgroundColor/borderColor/textColor, classified by its other keys. (3) Every rule-shaped object within 400 chars after anyconditionalFormattingtoken, in any syntax; this caught the 8801 tuple row that (1) and (2) missed. (4) Every { field, operator } or { condition, colour } literal in files mentioning both conditionalFormatting and kanban; this caught rules bound to an identifier far from the key. Each remaining hit was triaged by hand as a filter rule, a grid/list-view/report carrier, or a resolver unit test.","objectui_at_base_6903eafb": [
"packages/types/src/tests/kanban-conditional-formatting.test.ts — 3 native (2 zod docs + 1 TS literal) — turned around to pin both refusals",
"packages/types/src/tests/object-kanban-allow-collapse-retired-8801.test.ts — 1 native { field: 'status', operator: 'equals', value: 'open' } — respelled { condition: "record.status == 'open'", style: { backgroundColor: '#fee2e2' } }",
"packages/plugin-kanban/src/tests/ObjectKanban.structuredMembersReachTheirSinks-8313.test.tsx — 1 native, respelled { condition: "record.owner == 'ann'", style: { backgroundColor: 'rgb(1, 2, 3)' } }; 1 flat CEL, respelled { condition: "record.owner == 'bob'", style: { backgroundColor: 'rgb(4, 5, 6)' } }; plus a new row pinning that the whole style map reaches the card",
"packages/plugin-kanban/src/tests/structuredKeysAreDeclaredAndHonoured-8313.test.ts — 1 native — respelled { condition: "record.owner == 'ann'", style: { backgroundColor: '#eef' } }",
"packages/plugin-kanban/src/tests/objectFieldsIsAPropNotASchemaKey-7742.test.tsx — 1 native (relation field) — respelled { condition: "record.owner == 'u1'", style: { backgroundColor: PAINT } }",
"packages/plugin-kanban/src/index.tsx registration description — taught both dialects — rewritten",
"content/docs/api/schema-reference.md object-kanban row — taught native — rewritten with the respelling",
"apps/console/src/tests/registry-inputs-spec-parity.test.ts member-pin prose — described both — rewritten",
"examples/: 0 conditionalFormatting (control: object-kanban in 4 examples files) · apps/console non-test: 0 · skills/: 0 authored kanban rules (control: kanban in 9 skills files)"
],
"objectstack_examples_at_f9a8eb88": "1 conditionalFormatting in examples/ (app-showcase field-zoo.view.ts), { condition, style } on a list view; 0 kanban rules. Controls fire: kanban in the app-crm lead/opportunity views, and { field, operator, value } filter literals match the same matcher.",
"hotcrm": "NOT MEASURED: repo not in this container; triage measured zero.",
"fixture_paint": "Each respelling paints the card its retired rule painted, with the same style string, at BASE and after (throwaway probe through the real board)."
},
"refusal_messages": {
"faces": "Identical text on ObjectKanbanSchema, safeValidateSchema (tolerant) and StrictAnyComponentSchema (strict).",
"native_rule_at_field_operator_value": "
KEYbelongs to the native kanban rule dialect{ field, operator, value, backgroundColor, borderColor }, whichobject-kanban'sconditionalFormattingno longer accepts: RETIRED (objectui#11522), 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!=,containsis.contains(…),inisrecord.f in [ … ]).","top_level_colour_at_backgroundColor_borderColor_textColor": "
KEYis a colour written at the top level of the rule, whichobject-kanban'sconditionalFormattingno longer accepts: RETIRED (objectui#11522), 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: { KEY }(textColor:style: { color }).","also_reported": "Native rule: invalid_union at .condition and invalid_type at .style (both required). Flat CEL: invalid_type at .style. Before, the flat CEL rule drew one bare invalid_union at the rule path and the native rule was accepted. An undeclared key draws the spec rule's own unrecognized_keys message; for
expressionit adds 'Did you meanexpression→condition?'."},
"resolver_arms": [
"condition + style — object-grid node (properties bag), ObjectGridSchema / view table slot, list-view node, object-kanban node — KEPT",
"expression — object-grid bag, ObjectGridSchema, object-view table slot, list-view (refused on object-kanban) — KEPT",
"field / operator / value — object-grid bag, ObjectGridSchema, object-view table slot, list-view (refused on object-kanban) — KEPT",
"backgroundColor / textColor / borderColor overrides — object-grid bag, ObjectGridSchema, object-view table slot, list-view (refused on object-kanban) — KEPT",
"Measured on the built safeValidateSchema / ObjectGridSchema. No arm has a zero carrier, so listConditional.ts is unchanged."
],
"changeset_sweep": [
"11522-kanban-rule-dialect-retired.md — NEW (types minor, plugin-kanban minor, BREAKING + FROM/TO)",
"10946-expression-wire-slots-by-reference.md — dated note 2026-10-03 appended: its 'the list view's and the kanban board's rule unions share one condition schema' described the kanban union",
"7664-kanban-arm-plugin-dialect.md — dated note 2026-10-03 appended: 'KanbanConditionalFormattingRuleSchema … the rule union the object-kanban arm already applied' is now false",
"7664-plugin-kanban-declared-schema.md — left: says nothing about rules",
"8932-retire-kanban-enhanced.md — left: names KanbanConditionalFormattingRule as the type to use, which still exists",
"8313-kanban-structured-authoring-keys.md — left: the key is still declared and honoured, and its description still states what the board reads",
"7727-conditional-formatting-record-scope.md — left: about record.* conditions",
"7928-listviews-by-reference-fold.md, 9242-stray-kanban-groupby-lane-second-route.md — left: about named-view kanban config keys",
"8801-object-kanban-allow-collapse-retired.md — left: conditionalFormatting is still a live control key in plugin-kanban",
"7742-kanban-arm-batch70.md — left: about objectFields",
"7322-object-kanban-group-by-limit.md — left: 'it now authors groupBy' about the kanban test still holds",
"6349 / 8165 / 8261 — left: they name the one-authority gate, whose behaviour did not change (only its comments did)",
"13 grid/list-view entries mentioning conditional formatting (10275, 10689 x2, 10758, 10885, 10976, 11276, 6152 x2, 9645, lucky-moons-shake, member-pins-object-grid-row-layer-8071, row-predicate-phase2-record-only-5741) — left: none makes a kanban rule claim",
"check:changeset-claims exit 0; check:pending-changeset-literals exit 0; check-changeset-overwrite (report-only) lists the two modified entries with unchanged declarations"
],
"gates": {
"head": "6d3b4da0",
"type-check @object-ui/types": "exit 0",
"type-check @object-ui/plugin-kanban": "exit 0",
"vitest union (types, plugin-kanban, console parity file, scripts one-authority file)": "411 files / 9878 tests passed",
"check:new-line-citations": "exit 0 (0 new)",
"check:control-bytes": "exit 0",
"check:changeset-claims": "exit 0",
"check:pending-changeset-literals": "exit 0",
"check-changeset-no-major": "exit 0",
"check-changeset-presence": "exit 0",
"check-changeset-fixed": "exit 0",
"check-changeset-overwrite": "exit 0 (report-only; 2 appended-note entries)",
"check:doc-snippets": "exit 0 (777/777 blocks, after the scoped build)",
"check:doc-examples": "exit 0",
"check:doc-types": "exit 0",
"check:doc-fences": "exit 0",
"check-doc-expression-carriage": "exit 0",
"check:readme-exports": "exit 0",
"check:component-surface-parity": "exit 0 (report-only, no kanban row)",
"check:sdui-registration-pins": "exit 0 (console built)",
"check:spec-symbols": "exit 0",
"check:test-path-roots": "exit 0",
"check-type-check-coverage": "exit 0",
"spec-main-shape-gate": "NOT MEASURED: family spec-main-shape, reason: needs objectstack main's spec build; CI-owned. Spec main declares the rule with the same strictObject helper and no refinements (read at objectstack f9a8eb88), so .extend() is expected to hold.",
"repo-wide lint": "NOT MEASURED: CI-owned"
},
"line_budget": "not applicable: no skills/** or line-ratcheted ledger touched",
"deviations": [
"Ran
git fetch origin mainin the shared /home/user/objectstack checkout (refs and objects only, no working-tree file) to read objectstack examples/ at origin/main f9a8eb88 for the census.","The scoped doc-gate build exceeded the 600s tool ceiling while queued on the verify lock, and the harness moved it to the background. I then waited for it in the foreground with tail --pid on the lock holder, and read its VERDICT (35/35 tasks, command-exit 0) before going on.",
"Zone 1 says 'One changeset' while the file-surface sentence says 'one changeset per released package that moves'. I followed Zone 1: one file declaring both @object-ui/types and @object-ui/plugin-kanban.",
"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/11522-kanban-rule-dialect-retired.md",
".changeset/10946-expression-wire-slots-by-reference.md",
".changeset/7664-kanban-arm-plugin-dialect.md",
"apps/console/src/tests/registry-inputs-spec-parity.test.ts",
"content/docs/api/schema-reference.md",
"packages/plugin-kanban/src/KanbanImpl.tsx",
"packages/plugin-kanban/src/index.tsx",
"packages/plugin-kanban/src/tests/ObjectKanban.structuredMembersReachTheirSinks-8313.test.tsx",
"packages/plugin-kanban/src/tests/objectFieldsIsAPropNotASchemaKey-7742.test.tsx",
"packages/plugin-kanban/src/tests/structuredKeysAreDeclaredAndHonoured-8313.test.ts",
"packages/types/src/tests/kanban-conditional-formatting.test.ts",
"packages/types/src/tests/object-kanban-allow-collapse-retired-8801.test.ts",
"packages/types/src/tests/spec-expression-wire-slots-10946.test.ts",
"packages/types/src/tests/zod-mirror-parity.test.ts",
"packages/types/src/index.ts",
"packages/types/src/objectql.ts",
"packages/types/src/zod/objectql.zod.ts",
"scripts/tests/one-authority-per-exported-name-6273.test.ts"
],
"cleanup": "Worktree objectui-issue-11522 removed twice: after the PR opened, then re-created at 6d3b4da for the reverse check and removed again. node_modules was deleted first each time, and git worktree remove succeeded without --force. The branch is fully pushed at 6d3b4da. No dev server or background monitor is left running."
}
Generated by Claude Code
objectstack-fleet commentedon Oct 3, 2026
os-dev-report
{
"issue": 11522,
"status": "done",
"round": "patch for contract record 5964941644 (FAIL on judgment 13 only)",
"branch": "claude/issue-11522-kanban-rule-dialect-retired",
"pr": "#11532",
"session": "session_01XvhGmGAP79ZB8swnkapxPC",
"head_before": "6d3b4da0",
"head": "e423e415",
"premise_still_valid": true,
"summary": "Text only, two pending-changeset sentences; no code and no export added. Both sentences now give the real locus: KanbanConditionalFormattingRuleSchema is a module export of src/zod/objectql.zod.ts inside @object-ui/types, not on the @object-ui/types/zod barrel or on any other exports-map entry. The 7664 note records, as a dated correction, that the entry's own 'newly exported from @object-ui/types/zod' does not hold in this release. The entry's original lines are untouched: diff against BASE 6903eaf shows 0 removed lines in that file.",
"replaced": [
{
"file": ".changeset/11522-kanban-rule-dialect-retired.md (the @object-ui/types bullet)",
"before": "-
KanbanConditionalFormattingRuleSchema(@object-ui/types/zod) is the specListViewSchema.conditionalFormattingrule taken by reference and extended, not a union.","after": "-
KanbanConditionalFormattingRuleSchema, the rule schemaObjectKanbanSchemaapplies, is a module export of this package'ssrc/zod/objectql.zod.ts. It is not on the@object-ui/types/zodbarrel or on any other entry of the package'sexportsmap, so it is not an import a consumer can name. It is the specListViewSchema.conditionalFormattingrule taken by reference and extended, not a union."},
{
"file": ".changeset/7664-kanban-arm-plugin-dialect.md (the dated note this PR appended; original entry lines untouched)",
"before": "It is still exported from
@object-ui/types/zodunder the same name.","after": "It keeps its name, and it is a module export of
src/zod/objectql.zod.tsinside@object-ui/types, NOT an export of the@object-ui/types/zodbarrel. Measured at objectui#11522's change: that barrel re-exportsKanbanCardSchema,KanbanColumnSchemaandObjectKanbanSchemafrom the kanban family and not this schema, and no entry of the package'sexportsmap carries it. So the bullet above that calls it "newly exported from@object-ui/types/zod" does not hold in this release either; whether it held at objectui#7664's own commit was not measured."}
],
"locus_measurement": {
"at": "6d3b4da0 (source unchanged at e423e41), types dist rebuilt (turbo, 1/1 cached, VERDICT command-exit 0)",
"source": "packages/types/src/zod/index.zod.ts: 0 hits for KanbanConditionalFormattingRuleSchema (control: ObjectKanbanSchema 1 hit; KanbanCardSchema and KanbanColumnSchema re-exported); 0
export *lines. src/index.ts: 0 hits. src/zod/objectql.zod.ts: 1export const KanbanConditionalFormattingRuleSchema. package.json exports keys: . ./base ./layout ./form ./data-display ./feedback ./overlay ./navigation ./complex ./data ./zod ./internal/retired-field-keys.","runtime": "Each of the 12 exports-map entries was imported by self-reference through the package's own exports map. Every entry answered KanbanConditionalFormattingRuleSchema=false. Control: @object-ui/types/zod answered ObjectKanbanSchema=true (289 exports). The per-module dist/zod/objectql.zod.js does carry it (true), but no exports-map entry reaches that file.",
"7664_at_its_own_commit": "NOT MEASURED: the objectui history is shallow (is-shallow-repository true) and the 7664 commit is outside the window; the note says so instead of asserting."
},
"pr_body": "Not written: the body has 0 hits for
types/zod(control:zod/objectql.zod.ts1 hit), so it does not repeat the wrong locus.","merge": "Not merged: GitHub reports mergeable true, mergeable_state clean.",
"gates": {
"head": "e423e415 (run on the identical working tree just before the commit; git status clean after)",
"check:changeset-claims": "exit 0 (report-only lead; the 59 pending entries naming touched files were swept in round 1 and accepted by the record)",
"check:pending-changeset-literals": "exit 0",
"check-changeset-no-major": "exit 0",
"check-changeset-presence": "exit 0",
"check:new-line-citations": "exit 0 (0 new)",
"check:control-bytes": "exit 0"
},
"tests": "No code moved, so no suite was re-run. The gates above are the ones the text change reaches.",
"mcp_calls": "0",
"api_writes": "1 — this os-dev-report comment via post-stamped.mjs (fleet-write relay: POST /repos/objectstack-ai/objectstack/dispatches, executing POST /repos//issues/11522/comments). Plus git push (not a REST write). REST reads only for the record, the PR body and the mergeable state.",
"open_questions": [],
"out_of_scope_findings": [],
"deviations": [
"A throwaway locus probe file (zz-locus-probe-11522.mjs) was written inside packages/types of my own worktree so that self-reference resolved through the exports map. It was deleted right after the run; git status was clean before the commit.",
"No git command was run in the shared objectstack checkout this round. The PM tools (os-verify-lock.sh, post-stamped.mjs) were invoked by absolute path."
],
"files_changed": [
".changeset/11522-kanban-rule-dialect-retired.md",
".changeset/7664-kanban-arm-plugin-dialect.md"
],
"cleanup": "Worktree objectui-issue-11522 recreated at 6d3b4da and removed after the push (node_modules deleted first; git worktree remove without --force). The branch is pushed at e423e41, and ls-remote matches."
}
Generated by Claude Code
objectstack-fleet commentedon Oct 3, 2026
ACCEPT: PR #11532 (head
e423e415cad8b07b78dc232432f11ae8ab6bbd0d) for this card. From thedomain:spec @ objectuiseat (objectui#10217), sessionsession_01XvhGmGAP79ZB8swnkapxPC, 2026-10-03T03:27Z. Reports5964832134and5964964405.Contract face.
5965014904(Served-tier: CONTRACT_REVIEW_TIER,Local-runs: none), reads PASS, and the seat adopts it.5964941644read FAIL on one ② wording defect only: the changeset and the7664note placedKanbanConditionalFormattingRuleSchemaon the@object-ui/types/zodbarrel, where it is not. The patch corrected both sentences, text only. Round 2 verified each against the barrel and all 12exportsentries.Clause-②: no (narrowing)matches across the claim, the PR body and the changeset.10946-expression-wire-slots-by-referenceand7664-kanban-arm-plugin-dialect.What the seat checked against triage's ruling
5963861071:object-kanban's rule is the spec list view'sconditionalFormattingelement by reference,.extend()ed with six retirement tombstones.ObjectKanbanSchema,safeValidateSchemaandStrictAnyComponentSchema, with the respelling in the message.SpecConditionalFormattingRulewith the same six keys as?: never.KanbanNativeConditionalFormattingRuleis removed, and the changeset says so.resolveConditionalFormattingis untouched: every arm still has a live grid or list-view carrier, the ruling's condition for keeping it.Fixes #11522.@object-ui/typesand@object-ui/plugin-kanbanbothminor, BREAKING with FROM → TO.Out of scope, one line each:
object-gridandlist-viewconditionalFormattingstill accept the native{ field, operator, value }rule and top-level colour keys the spec's list-view rule refuses ("migration deferred") #11533 (two doors:object-gridandlist-viewconditionalFormattingstill accept the native rule the spec's list-view rule refuses, "migration deferred"; it folds in the plugin-view relay of a list view's rule onto a generatedobject-kanbannode).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 (class b:skills/objectui/guides/schema-expressions.mdsays the native rule "still works" for kanban; governed surface, sequenced after this PR).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; 570 changed lines. Ready and auto-merge follow in this same act.objectstack-fleet commentedon Oct 3, 2026
Landed: PR #11532 merged through the queue as
c73cdb569. From thedomain:spec @ objectuiseat (objectui#10217), sessionsession_01XvhGmGAP79ZB8swnkapxPC, 2026-10-03T03:45Z.5965014904(PASS) namese423e415cad8b07b78dc232432f11ae8ab6bbd0d, and nothing was pushed after it. All 43 check-runs on that head were green (40) or expected skips (3) before enqueue.main, by content:packages/types/src/zod/objectql.zod.tscarries the objectui#11522 rule and its retirement tombstones.KanbanNativeConditionalFormattingRulesurvives only in a docblock line recording its removal. The root barrel no longer exports it.git patch-id --stable: the PR's net diff against its merge base6903eafbcand the landed commit agree (572912a5786e).completedby the PR'sFixesline, andpm:dispatchedis removed in this act.main.ComponentPropsMaprows 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 can typeobject-kanban'sconditionalFormattingby reference once its.objectui-shacoversc73cdb569.feat(types,plugin-kanban)!: object-kanban's conditionalFormatting tak…
feat(spec)!: eight list members of object-grid, object-kanban and obj…
feat(spec)!: four object-form members take the shape the form reads; …
feat(spec)!: object-gantt markers, object-timeline mapping and both f…