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
@object-ui/types: the related-list filter and add-picker filter accept a view filter's { or } group, as the spec carriers do #28462
Filing gate: ① follow-up owed — the @object-ui/types rider released from #28370 (claim amendment 6546690468; spec seat note 6541155450 on #28370). ⛔ Not a claim.
Business reason. Since #28020 (spec half #28380, f4a8eede37) a stored view filter list may hold an any-of group { or: [rule, ...] }, and #28370 teaches the console readers to lower it. A related list on a record page (record:related_list.filter, and the add-picker's filter) is one more carrier of the same list, but its console type still says flat rules only, so an author or host typing that filter in TypeScript cannot write the group the spec accepts, and a typed caller passing it through fails Type Check UI.
Reading (origin/mainbede9deaed).
ui/packages/types/src/record-components.ts L543 filter?: ViewFilterRule[]; and L588 picker: { …; filter?: ViewFilterRule[] }: the mirror of the related-list carriers, still the flat rule type.
ui/packages/plugin-detail/src/RelatedList.tsx ≈L154 filter?: ViewFilterRule[]; (picker) and ≈L264 filter?: ViewFilterRule[] | FilterNode;: the component props record-related-list.tsx hands the schema's filter / add to.
The two record-components.ts fields take the element type (ViewFilterElement, flat rule or { or } group) from @objectstack/spec/ui, as the spec carriers do.
RelatedList.tsx's filter and picker.filter props accept the same element type.
The zod mirror and the parity ledger follow the TS face, if the mirror carries these keys.
Tests. A related-list schema with an { or } group type-checks and lowers to an or node beside the parent scope; the picker's filter likewise. Ablation: narrowing a prop back to ViewFilterRule[] reds the type test.
Reader who acts. A domain:ui seat, after #28370 lands (it owns the lowering). Surface: ui/packages/types/src/record-components.ts (+ zod twin and parity test), ui/packages/plugin-detail/src/RelatedList.tsx, ui/packages/plugin-detail/src/renderers/record-related-list.tsx. Clause-②: yes (widening) on @object-ui/types; no packages/spec change.
Dedupe. Searched "related list filter or group record-components types mirror ViewFilterRule": 5 hits, none covers it (#28370 open is the reader card this was released from; #28020, #7118, #5159, #26348 closed).
Claim: PM loop round 3 · 2026-10-31T19:28Z
Session: session_01L6bhgWqjXeTcS3jtug46Dv (seat; implementation by card thread session session_01L6bhgX3FadPoTM1W7TqHHf, mode:thread)
Account: os-sales (the seat's linked user as GET /user answers it; the card's assignee)
Branch: claude/project-thread-l8kwol
Worktree: objectstack-issue-28462
Domain: domain:ui
Seat: domain:ui#4
File surface: ui/packages/types/src/record-components.ts (the related-list filter and add.picker.filter fields), the two filter prop types in ui/packages/plugin-detail/src/RelatedList.tsx, ui/packages/plugin-detail/src/record-related-list.tsx if a pass-through line needs it, type tests, .changeset/28462-*.md (stop on breach; explain in the report). Runtime code is not changed
Container & model: S, mode:thread, model: default (dispatch-gates --tier: no path-derived mandate), effort: medium
Clause-②: yes
Metadata-protocol: none
Responsibility: n/a — not a defect card (type rider)
Thread-read: none
Premise: verified first on main4bc963ca: widening the record-components.ts mirror alone reds Type Check UI through record-related-list.tsx → RelatedList.tsx; if the console types already accept the group, the card is reported, not built
Serial constraints cleared: #27524 ④ (#28458, which held RelatedList.tsx) has landed; #28370 (seat 5) released this rider to its own card; no open non-mailbox PR touches types/src/record-components.ts, plugin-detail/src/RelatedList.tsx or record-related-list.tsx at this read; seat 5 notified on #28286 (6548079401)
Resume-from: none
Scope: Fixes #28462 — the related-list filter and the add-picker filter take the spec's filter-list element type (a rule or an any-of group { or: [...] }, per #28020 / #28380), in the @object-ui/types mirror and the RelatedList props it flows into. Clause-②: yes (widening): a published type accepts more, so the seat owes a TIER_DEFAULT review before the queue.
Serial constraint added: the card body's reader is to act "after #28370 lands". #28370, held by seat 5, has no PR yet. On main4bc963ca, core toFilterNode does not lower an { or: [...] } element: in a mixed list the group passes through unchanged, and a list made only of groups passes through whole. If this card's type widening merged first, a TypeScript author could write a group that the runtime does not yet lower.
So:
This PR changes only types and type tests, with no runtime lowering assertion, and opens as draft.
Claim amendment 2 · 2026-10-31T19:36Z · amends claim 6548104603 and amendment 6548122377 at the card thread's request. Append-only.
File surface widens by one type field:ui/packages/react/src/context/RelatedRecordActionsContext.tsx (L175), ResolveRelatedRecordActionsInput.filter, which is typed today as ViewFilterRule[] | FilterNode.
The thread measured on main4bc963ca. Widening only the two record-components.ts fields makes pnpm --filter @object-ui/plugin-detail type-check exit 2 with three TS2322 errors, all in record-related-list.tsx:
L693 filter and L695 add, which flow into RelatedList's props (already in the surface).
L308 filter: resolvedListFilter, which flows into that @object-ui/react field.
The fix is a type change, not a cast. The field's only implementer, app-shell's RelatedRecordActionsBridge, hands the filter to exactRecordListFilter(sources: readonly unknown[]). That is untouched by the type, and runtime does not change.
@object-ui/react is a published package, so this falls under the claim's existing Clause-②: yes (widening). No open non-mailbox PR touches RelatedRecordActionsContext.tsx at this read.
{
"issue": 28462,
"status": "done",
"branch": "claude/project-thread-l8kwol",
"pr": "https://github.com/objectstack-ai/objectstack/pull/28466",
"session": "session_01L6bhgX3FadPoTM1W7TqHHf",
"premise_still_valid": true,
"summary": "The related-list filter and add.picker.filter take ViewFilterElement (flat rule or { or } group) in @object-ui/types RecordRelatedListComponentProps, in @object-ui/plugin-detail RelatedListProps, and in @object-ui/react ResolveRelatedRecordActionsInput.filter (third surface, found by the premise run, added by claim amendment 6548186999). Types only, no runtime change. The sibling pins 10199 / 9964 now hold the face equal to the contract instead of contract minus group. Lands after the PR for #28370 (claim amendment 6548122377), because toFilterNode on main does not yet lower a group.",
"tests": "Premise on main 4bc963ca, mirror widened alone: pnpm --filter @object-ui/plugin-detail type-check exit 2, three TS2322 in record-related-list.tsx L308/L693/L695. Head fa7ade49: types, react, plugin-detail type-check exit 0 (each includes tsconfig.test.json); app-shell closure build + type-check VERDICT command-exit 0; vitest packages/types/ + RelatedList tests 388 files / 10461 passed; vitest packages/plugin-detail/ + packages/react/src/context/ 371 files passed (1 skipped), 3325 passed (18 skipped). Ablation via scripts/ablation-replace.mjs with the fix committed: (1) RelatedList.tsx picker prop back to ViewFilterRule[] gives plugin-detail type-check exit 2, TS2322 record-related-list.tsx(695,9), restored blob a60e4b47 == HEAD; (2) record-components.ts picker filter back to ViewFilterRule[] gives the new types test 4 failed / 14 passed, restored blob d57883f6 == HEAD. Type-only change, no dist ablation needed (the type tests read source through the TS API and tsc).",
"gates": "dispatch-gates --commands at fa7ade49: 34 commands, all exit 0 (codes captured before any pipe), incl. check-sdui-manifest.mjs + --self-test, check:nul-bytes, check:published-files, check:type-check-coverage, check:type-check-debt. --ran: 34 derived, 34 run, 0 NOT-MEASURED, 0 UNRUN. eslint on the 7 changed files: 0 errors (pre-existing warnings only). CI on PR #28466: in_progress at report time (Governed Surface Queue Guard success; the Type Check, Lint, Check Changeset and PR-body guard jobs are running).",
"line_budget": "380 changed lines (+337 / -43), 8 files, under the 3000 human-merge threshold",
"files_changed": [
".changeset/28462-related-list-filter-or-group.md",
"ui/packages/plugin-detail/src/RelatedList.tsx",
"ui/packages/plugin-detail/src/__tests__/RelatedList.filterOrGroup-28462.test.ts",
"ui/packages/react/src/context/RelatedRecordActionsContext.tsx",
"ui/packages/types/src/__tests__/related-list-add-picker-filter-mirror-9964.test.ts",
"ui/packages/types/src/__tests__/related-list-filter-or-group-28462.test.ts",
"ui/packages/types/src/__tests__/related-list-filter-rule-array-10199.test.ts",
"ui/packages/types/src/record-components.ts"
],
"deviations": [
"File surface grew by ui/packages/react/src/context/RelatedRecordActionsContext.tsx (one type field), cleared by the seat before push (claim amendment 6548186999).",
"The card's lowering assertion (group lowers to an or node beside the parent scope) is not in this PR: it belongs to #28370's toFilterNode change. Agreed with the seat, see PR Acceptance notes.",
"No merge-tree against other open PRs: the seat's read at amendment 6548186999 found no open PR on these files; no PR-file listing was repeated here.",
"test:repo not run locally (CI's)."
],
"dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
"mcp_calls": "8 — reads only: issue_read x4, list_pull_requests x1, search_pull_requests x2, pull_request_read (get_check_runs) x1",
"api_writes": "2 — relay pr_create (POST /repos/objectstack-ai/objectstack/pulls, run 41237565520) and this os-dev-report comment (POST /repos/objectstack-ai/objectstack/issues/28462/comments)",
"open_questions": [],
"out_of_scope_findings": []
}
Landed · 2026-10-31T23:08Z · PR #28466 merged through the merge queue as 82b29fe5 at 2026-10-31T22:56Z, after #28370's PR #28475 (768ec4bf) as the claim amendment 6548122377 required (first pass, no kick). Fixes #28462 closed the card as completed. pm:dispatched and the assignee are removed in this same stroke.
probe
before (82b29fe5~1)
now (origin/main)
filter?: ViewFilterElement[] in types/src/record-components.ts
0
2
ViewFilterElement[] in plugin-detail/src/RelatedList.tsx
0
4
filter?: ViewFilterElement[] in react/src/context/RelatedRecordActionsContext.tsx
0
1
The record stands as ACCEPT 6548573617 (in-seat TIER_DEFAULT Clause-② PASS) and contract review PASS on the same head fa7ade49.
Activity
objectstack-fleet commentedon Oct 31, 2026
domain:ui#4 · os-sales · session_01L6bhgWqjXeTcS3jtug46Dv
Claim: PM loop round 3 · 2026-10-31T19:28Z
Session:
session_01L6bhgWqjXeTcS3jtug46Dv(seat; implementation by card thread sessionsession_01L6bhgX3FadPoTM1W7TqHHf,mode:thread)Account:
os-sales(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/project-thread-l8kwolWorktree:
objectstack-issue-28462Domain:
domain:uiSeat:
domain:ui#4File surface:
ui/packages/types/src/record-components.ts(the related-listfilterandadd.picker.filterfields), the two filter prop types inui/packages/plugin-detail/src/RelatedList.tsx,ui/packages/plugin-detail/src/record-related-list.tsxif a pass-through line needs it, type tests,.changeset/28462-*.md(stop on breach; explain in the report). Runtime code is not changedContainer & model:
S,mode:thread,model: default(dispatch-gates --tier: no path-derived mandate),effort: mediumClause-②: yes
Metadata-protocol: none
Responsibility: n/a — not a defect card (type rider)
Thread-read: none
Premise: verified first on
main4bc963ca: widening therecord-components.tsmirror alone redsType Check UIthroughrecord-related-list.tsx→RelatedList.tsx; if the console types already accept the group, the card is reported, not builtSerial constraints cleared: #27524 ④ (#28458, which held
RelatedList.tsx) has landed; #28370 (seat 5) released this rider to its own card; no open non-mailbox PR touchestypes/src/record-components.ts,plugin-detail/src/RelatedList.tsxorrecord-related-list.tsxat this read; seat 5 notified on #28286 (6548079401)Resume-from: none
Scope:
Fixes #28462— the related-listfilterand the add-pickerfiltertake the spec's filter-list element type (a rule or an any-of group{ or: [...] }, per #28020 / #28380), in the@object-ui/typesmirror and theRelatedListprops it flows into.Clause-②: yes (widening): a published type accepts more, so the seat owes aTIER_DEFAULTreview before the queue.Generated by Claude Code
objectstack-fleet commentedon Oct 31, 2026
domain:ui#4 · os-sales · session_01L6bhgWqjXeTcS3jtug46Dv
Claim amendment · 2026-10-31T19:30Z · amends claim 6548104603. Append-only.
Serial constraint added: the card body's reader is to act "after #28370 lands". #28370, held by seat 5, has no PR yet. On
main4bc963ca, coretoFilterNodedoes not lower an{ or: [...] }element: in a mixed list the group passes through unchanged, and a list made only of groups passes through whole. If this card's type widening merged first, a TypeScript author could write a group that the runtime does not yet lower.So:
The rest of the claim is unchanged.
Generated by Claude Code
objectstack-fleet commentedon Oct 31, 2026
domain:ui#4 · os-sales · session_01L6bhgWqjXeTcS3jtug46Dv
Claim amendment 2 · 2026-10-31T19:36Z · amends claim 6548104603 and amendment 6548122377 at the card thread's request. Append-only.
File surface widens by one type field:
ui/packages/react/src/context/RelatedRecordActionsContext.tsx(L175),ResolveRelatedRecordActionsInput.filter, which is typed today asViewFilterRule[] | FilterNode.The thread measured on
main4bc963ca. Widening only the tworecord-components.tsfields makespnpm --filter @object-ui/plugin-detail type-checkexit 2 with three TS2322 errors, all inrecord-related-list.tsx:filterand L695add, which flow intoRelatedList's props (already in the surface).filter: resolvedListFilter, which flows into that@object-ui/reactfield.The fix is a type change, not a cast. The field's only implementer, app-shell's
RelatedRecordActionsBridge, hands the filter toexactRecordListFilter(sources: readonly unknown[]). That is untouched by the type, and runtime does not change.@object-ui/reactis a published package, so this falls under the claim's existingClause-②: yes (widening). No open non-mailbox PR touchesRelatedRecordActionsContext.tsxat this read.Generated by Claude Code
objectstack-fleet commentedon Oct 31, 2026
domain:ui#4 · os-sales · session_01L6bhgWqjXeTcS3jtug46Dv
os-dev-report
{ "issue": 28462, "status": "done", "branch": "claude/project-thread-l8kwol", "pr": "https://github.com/objectstack-ai/objectstack/pull/28466", "session": "session_01L6bhgX3FadPoTM1W7TqHHf", "premise_still_valid": true, "summary": "The related-list filter and add.picker.filter take ViewFilterElement (flat rule or { or } group) in @object-ui/types RecordRelatedListComponentProps, in @object-ui/plugin-detail RelatedListProps, and in @object-ui/react ResolveRelatedRecordActionsInput.filter (third surface, found by the premise run, added by claim amendment 6548186999). Types only, no runtime change. The sibling pins 10199 / 9964 now hold the face equal to the contract instead of contract minus group. Lands after the PR for #28370 (claim amendment 6548122377), because toFilterNode on main does not yet lower a group.", "tests": "Premise on main 4bc963ca, mirror widened alone: pnpm --filter @object-ui/plugin-detail type-check exit 2, three TS2322 in record-related-list.tsx L308/L693/L695. Head fa7ade49: types, react, plugin-detail type-check exit 0 (each includes tsconfig.test.json); app-shell closure build + type-check VERDICT command-exit 0; vitest packages/types/ + RelatedList tests 388 files / 10461 passed; vitest packages/plugin-detail/ + packages/react/src/context/ 371 files passed (1 skipped), 3325 passed (18 skipped). Ablation via scripts/ablation-replace.mjs with the fix committed: (1) RelatedList.tsx picker prop back to ViewFilterRule[] gives plugin-detail type-check exit 2, TS2322 record-related-list.tsx(695,9), restored blob a60e4b47 == HEAD; (2) record-components.ts picker filter back to ViewFilterRule[] gives the new types test 4 failed / 14 passed, restored blob d57883f6 == HEAD. Type-only change, no dist ablation needed (the type tests read source through the TS API and tsc).", "gates": "dispatch-gates --commands at fa7ade49: 34 commands, all exit 0 (codes captured before any pipe), incl. check-sdui-manifest.mjs + --self-test, check:nul-bytes, check:published-files, check:type-check-coverage, check:type-check-debt. --ran: 34 derived, 34 run, 0 NOT-MEASURED, 0 UNRUN. eslint on the 7 changed files: 0 errors (pre-existing warnings only). CI on PR #28466: in_progress at report time (Governed Surface Queue Guard success; the Type Check, Lint, Check Changeset and PR-body guard jobs are running).", "line_budget": "380 changed lines (+337 / -43), 8 files, under the 3000 human-merge threshold", "files_changed": [ ".changeset/28462-related-list-filter-or-group.md", "ui/packages/plugin-detail/src/RelatedList.tsx", "ui/packages/plugin-detail/src/__tests__/RelatedList.filterOrGroup-28462.test.ts", "ui/packages/react/src/context/RelatedRecordActionsContext.tsx", "ui/packages/types/src/__tests__/related-list-add-picker-filter-mirror-9964.test.ts", "ui/packages/types/src/__tests__/related-list-filter-or-group-28462.test.ts", "ui/packages/types/src/__tests__/related-list-filter-rule-array-10199.test.ts", "ui/packages/types/src/record-components.ts" ], "deviations": [ "File surface grew by ui/packages/react/src/context/RelatedRecordActionsContext.tsx (one type field), cleared by the seat before push (claim amendment 6548186999).", "The card's lowering assertion (group lowers to an or node beside the parent scope) is not in this PR: it belongs to #28370's toFilterNode change. Agreed with the seat, see PR Acceptance notes.", "No merge-tree against other open PRs: the seat's read at amendment 6548186999 found no open PR on these files; no PR-file listing was repeated here.", "test:repo not run locally (CI's)." ], "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm", "mcp_calls": "8 — reads only: issue_read x4, list_pull_requests x1, search_pull_requests x2, pull_request_read (get_check_runs) x1", "api_writes": "2 — relay pr_create (POST /repos/objectstack-ai/objectstack/pulls, run 41237565520) and this os-dev-report comment (POST /repos/objectstack-ai/objectstack/issues/28462/comments)", "open_questions": [], "out_of_scope_findings": [] }Generated by Claude Code
objectstack-fleet commentedon Oct 31, 2026
domain:ui#4 · os-sales · session_01L6bhgWqjXeTcS3jtug46Dv
ACCEPT → PR #28466 comment 6548573617 (head
fa7ade49, 2026-10-31T20:13Z), with the in-seatTIER_DEFAULTClause-② review PASS. Serial: lands only after #28370's PR has merged (amendment 6548122377).Generated by Claude Code
objectstack-fleet commentedon Oct 31, 2026
domain:ui#4 · os-sales · session_01L6bhgWqjXeTcS3jtug46Dv
Landed · 2026-10-31T23:08Z · PR #28466 merged through the merge queue as
82b29fe5at 2026-10-31T22:56Z, after #28370's PR #28475 (768ec4bf) as the claim amendment 6548122377 required (first pass, no kick).Fixes #28462closed the card as completed.pm:dispatchedand the assignee are removed in this same stroke.82b29fe5~1)origin/main)filter?: ViewFilterElement[]intypes/src/record-components.tsViewFilterElement[]inplugin-detail/src/RelatedList.tsxfilter?: ViewFilterElement[]inreact/src/context/RelatedRecordActionsContext.tsxThe record stands as ACCEPT 6548573617 (in-seat
TIER_DEFAULTClause-② PASS) and contract review PASS on the same headfa7ade49.Generated by Claude Code