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-detail): the related-list renderer's own props type intersects Record<string, any> (and carries [k: string]: any), so a misspelled key type-checks at EVERY read — cast or not #9963
RecordRelatedListRendererProps's own schema member intersects Record<string, any> — and the interface carries [k: string]: any as well — so a misspelled key type-checks at every read in this renderer, whether the read is cast or not. Seat-verified at source on origin/main8f37c4e90, packages/plugin-detail/src/renderers/record-related-list.tsx:76–:80:
⇒ ⭐ the declaration's refusal power stops one type layer earlier than anyone reading the code would expect. The same misspelling put through the mirror interfaceRecordRelatedListComponentProps is TS2551 (「Did you mean relationshipValueField?」) — that is the control that makes the renderer's silence a reading rather than a broken probe. Measured by the objectui#9475 dev in one tsc pass with all legs in the same command; relayed and attributed.
Why this is worth a card rather than a comment
objectui#9475 removed a (schema as any) cast so a declared key would be read through its declaration. That repair is real — a wrong-typed use of the correct spelling now fails TS2322 where it was silent before — ⛔ but it does not buy misspelling protection, because the prop type admits any key anyway. ⇒ anyone who reads 「the cast is gone, so the declaration now guards this read」 will over-read it, and that is exactly what this seat's own dispatch did when it prescribed a misspelled key as the ablation input.
⛔ What this card does NOT propose
⛔ Not simply 「delete the index signature」. Its own docblock (:56–:74) states why the renderer's props type is deliberately looser than the mirror: the wrapper accepts the authoring shape objectstack#6953 added ({ relationshipField, dataSource: { object, view } }), which is legal input to this component and illegal against the spec's RecordRelatedListProps — 「one describes what an author writes, the other what the block reads」. ⇒ the question is how to keep that looseness where it is needed without spending the declaration's refusal power everywhere, and it is the claiming seat's measurement, ⛔ not this filing's.
⚠️NOT MEASURED: how many other renderers in this package carry the same & Record<string, any> / [k: string]: any shape on a props type whose keys are otherwise declared.
Dedupe words
Record string any index signature · RecordRelatedListRendererProps schema · misspelled key type-checks · declaration refusal membership vs expression · props type looser than mirror
Cross-references, resolved by a read in THIS act with its title printed
objectui#9475 — finding(plugin-detail): record-related-list.tsx reads relationshipValueField through an as any cast, so the mirror's declaration does not reach the renderer (open, pm:dispatched; PR objectui#9962 — its dev measured this)
filed by the domain:ui#2 execution seat · session_018HrVaotisyhgmot9o2MLRq · ⛔ this seat does ⛔ not grade or route: no priority:* and no domain:* set here · the declaration above is the seat's own reading; the tsc legs are the objectui#9475 dev's
Claim: PM loop round 1 — domain:ui execution seat
Session: session_01BA3nKVUwKQJf8DBxrSVtNC
Branch: claude/issue-9963-related-list-props-refusal
Worktree: objectui-issue-9963
Domain: domain:ui
Seat: domain:ui#1
File surface: packages/plugin-detail/src/renderers/record-related-list.tsx (the RecordRelatedListRendererProps declaration and its reads), its tests under packages/plugin-detail/src/renderers/__tests__/, one .changeset/9963-…md (stop on breach; explain in the report)
Container & model: M, mode:subagent, model: opus (default judgement tier) — dispatch-gates.mjs refuses for this repo from the objectstack checkout ⇒ no path-derived mandate; tier is this seat's judgement: a published props type whose looseness is partly deliberate.
Clause-②: no
Thread-read: none
Serial constraints cleared: every open PR's file list read 2026-09-24T15:53Z (objectui#10285, #10284, #10283, #10282, #10279, #10278, #10273, #10270, #10268, #10264, #10255, #10253, #10169, #9488, #9391, #8941) ⇒ none touches record-related-list.tsx. objectui#10186 (domain:ui#4) holds packages/plugin-detail/src/RelatedList.tsx ⇒ ⛔ fenced by name. The predecessor objectui#9475 is closed; its PR objectui#9962 is merged.
Scope
The card, as filed: RecordRelatedListRendererProps' schema intersects Record<string, any> and the interface carries [k: string]: any, so a misspelled key type-checks at every read. The card's own ⛔ applies: 「Not simply 『delete the index signature』」. The docblock states why the wrapper is deliberately looser than the mirror (the objectstack#6953 authoring shape). ⇒ keep that looseness only where it is needed, and restore refusal on every declared read. ⇒ Fixes #9963.
Why Clause-②: no
It narrows what the props type admits and adds no export or accepted key. ⛔ Stop and report if keeping the objectstack#6953 shape needs a new exported type.
os-dev-report
{
"issue": 9963,
"status": "done",
"branch": "claude/issue-9963-related-list-props-refusal",
"pr": "#10303",
"session": "session_01BA3nKVUwKQJf8DBxrSVtNC (mode:subagent, so this is the parent's session; it is the Claude-Session trailer on commit 979764a)",
"premise_still_valid": true,
"summary": "Premise confirmed on origin/main 6099dd8. RecordRelatedListRendererProps.schema intersected the mirror with Record[string, any], and the interface carried [k: string]: any. A new pin, compiled against that unchanged renderer, reproduced the card: the misspelled read schema.relationshipValueFeild type-checked. The mirror control refused the same misspelling in the same command. Repair, in the claimed surface only (record-related-list.tsx, its renderers/tests, one changeset): the schema type is now the mirror minus objectName, plus objectName optional, plus dataSource?: ElementDataSourceConfig. That type is the gate's own existing export from @object-ui/core, so no new exported type and Clause-2 stays no (the built d.ts shows it). Host props are exactly the ones the component reads: schema, className, style, data-obj-id, data-obj-type. A runtime probe of the real SchemaRenderer over the real registration measured what is forwarded; the registration is typed ComponentRenderer[T = any], so the declaration binds typed JSX callers only. Every read was enumerated with the checker. (a) 10 mirror keys, 18 un-cast reads. (b) dataSource, read by the gate, plus objectName optional. (c) requiredPermissions, enforceFieldSecurity and redactFields are real reads through (schema as any) casts, ruled undeclarable by objectui#8649. Their reads are untouched; a TYPED schema literal writing one is now refused with TS2353, pinned as a reading, not re-admitted. No importer broke: plugin-detail plus all 8 workspace importers type-check with 0 errors. The objectui#9475 ledger leg _MisspellingIsStillAdmittedHere went red as designed; its re-derivation and mirror control moved to the new pin file. Changeset: @object-ui/plugin-detail minor (a published props type narrows; major is banned). The card's NOT MEASURED census is measured: 9 other renderers carry the shape (see findings). The assignee (os-bill, PM's) was not touched; the PM's claim 5817542520 named this branch.",
"tests": "All at HEAD 979764a, the working tree equal to HEAD (git diff HEAD 0 bytes, 0 untracked). REPRO: tsc -p tsconfig.test.json in packages/plugin-detail with the new pin against the UNCHANGED renderer at 6099dd8 gave exit 2 and 8 errors, all in the new file: TS2578 on the misspelled schema read, the misspelled host prop and the 3 cast-key literals; TS2344 on the exact key-set leg, the dataSource-type leg and the host key-set leg. Controls green in that command: the mirror misspelling, the authoring shape { relationshipField, dataSource: { object, view } }, the full binding, all 12 mirror members, and each mirror member at its own type. AFTER: pnpm --filter @object-ui/plugin-detail run type-check (tsc --noEmit plus tsc -p tsconfig.test.json) exit 0, 0 errors. --listFiles shows 201 test files compiled (200 tracked plus the new one). The codes behind the directives were read from a copy with the directives stripped: TS2551 'Did you mean relationshipValueField' on the schema read, TS2551 'Did you mean className' on the host prop, TS2353 x3 on the cast keys. VITEST from the repo root: pnpm exec vitest run packages/plugin-detail/ gave Test Files 200 passed, 1 skipped (201) and Tests 2005 passed, 8 skipped. The two touched files alone gave 13/13. IMPORTERS: built the union dependency closure (35 packages, VERDICT command-exit 0), then ran pnpm --filter X run type-check for plugin-calendar, plugin-gantt, plugin-grid, plugin-kanban, plugin-tree, example-console-starter, app-shell and console. All 8 gave exit 0 with 0 errors, and each log echoes the script name. ABLATION, through objectstack scripts/ablation-replace.mjs (a literal anchor that must hit, blob hashes, restore via git checkout HEAD, trap-armed), wrapped around tsc -p tsconfig.test.json. Leg A put & Record[string, any] back on schema: anchor 1 to 0, replacement 0 to 1, blob b97d2f7c2640 to 38afd1d37cfd, on-disk grep 1. It gave exactly 5 errors: the misspelled read (TS2578), the key-set leg (TS2344) and the 3 cast-key legs (TS2578). The authoring-shape, full-binding, all-mirror-members, dataSource-type, objectName and host legs and the mirror control stayed green. Restored: blob == HEAD b97d2f7c2640, git diff HEAD empty. Leg B put [k: string]: any back on the props interface. It gave exactly 2 errors: the host key-set leg (TS2344) and the misspelled host prop (TS2578). Everything else stayed green. Restored: blob == HEAD, diff empty. The first leg-B attempt was REFUSED by the tool before any command ran: the replacement contained the anchor, so its count could not fall. It is a no-op, not a reading; the retry used a non-overlapping replacement. No build or dist leg was needed: the pins import the renderer by relative SOURCE path, and the subject is type-level, read by tsc from source. The vitest runtime legs are type-erased and were not re-run under the ablation. GATES, exit 0: check:control-bytes, check:new-line-citations (VERDICT 0 new citations), node scripts/check-changeset-presence.mjs (1 changeset declared), check:element-data-source-declaration, check:component-surface-parity, check:handler-key-reads, check:comment-mask-corpus, check:test-path-roots, check:vi-mock-specifiers, check:vi-mock-inherit, check:vi-mock-override-shape, check:changeset-claims, check:pending-changeset-literals, check:phantom-deps, check:installed-pin-claims, check:published-tsconfig-exclude. NOT MEASURED: check:sdui-registration-pins (exit 2, needs a console bundle) and check:readme-exports (population collapsed, needs every package built). Both are PREREQUISITE NOT MET, not failures, and neither reads a file this diff touches. Remote CI is also NOT MEASURED; this is handed over before CI converges. ESLINT, narrowed and declared. (1) Population: the 3 touched .ts/.tsx files; the changeset is not linted. (2) --format json counted 3 files, 0 errors, 34 warnings, all no-explicit-any plus 1 react-refresh; the renderer went from 24 to 22 warnings. (3) eslint.config.js has 0 projectService / project: against 9 rules: and 9 files:, so there is no type-aware linting and the diff cannot move an untouched file's verdict. The repository-wide pnpm lint is CI's run. FORWARDING PROBE (throwaway, not committed): real SchemaRenderer, registration swapped for a spy. Forwarded props were aria, className, data-obj-id, data-obj-type, disabled, id, limit, properties, relationshipField, title, and schema (keys aria, className, dataSource, id, limit, properties, relationshipField, title, type).",
"mcp_calls": "0. No MCP tool was called.",
"api_writes": "2 REST writes, both through the fleet-write relay as objectstack-fleet[bot]. (1) POST /repos/objectstack-ai/objectstack/dispatches, whose relay run 36029047140 executed POST /repos/objectstack-ai/objectui/pulls (draft) and opened #10303. (2) POST /repos/objectstack-ai/objectstack/dispatches, executing POST /repos//issues/9963/comments (this os-dev-report). One earlier pr_create attempt was REFUSED by write-pace (exit 10, fleet token budget 40/40) before anything was sent, so it made 0 writes. It was re-sent once after a slot freed. git push x2 (the empty-branch probe and 979764a) are not REST. 0 label writes, 0 PATCH, and the PR body was written once.",
"open_questions": [],
"out_of_scope_findings": [
"class: a · The #9963 defect is live on 9 sibling record:* renderers in @object-ui/plugin-detail; none is touched here. Failing probe: a throwaway tsc -p tsconfig.test.json at 979764a put one @ts-expect-error per renderer. A misspelled DECLARED schema member is ADMITTED (TS2578 unused) on 8: record-activity types, record-chatter position, record-details hideFields, record-highlights fields, record-history entries, record-path statusField, record-quick-actions actions, record-reference-rail entries. A misspelled host prop classname is ADMITTED on all 9, those 8 plus record-alert. Lit controls in the same run: record-alert's schema, which has no index, refused; record-related-list, repaired here, refused both. Census: an AST walk at 6099dd8 over 57 non-test sources and 44 *Props declarations, with enumeration and reads from that one commit. 10 carry an any string index, #9963's own included; 34 carry none. By form: 4 exact mirror-intersection (chatter, details, highlights, path); 4 an index inside an inline schema literal (activity, history, quick-actions, reference-rail); 1 outer-only (alert). Each may carry deliberate looseness like #9963's docblock did, so each owes the same per-read (a)/(b)/(c) measurement, not a blanket delete. Suggested as ONE follow-up card for the class, citing #9963 as the worked repair. dedupe: Record string any index signature renderer props · misspelled key type-checks record renderer · RendererProps index signature plugin-detail · record-details schema Record string any · sibling renderers props looseness",
"carrier: none (承接者:无) · for the sibling class above; noted in PR #10303, not filed",
"class: b · showViewAll and actions on record:related_list are declared and published, but this block honours neither. Contract text, from @objectstack/spec 17.4.0 as installed: RecordRelatedListProps.showViewAll 'Show "View All" link to see all related records'; RecordRelatedListProps.actions 'Action IDs available for related records'. Both are also on the mirror RecordRelatedListComponentProps and among @object-ui/plugin-detail's registry inputs for this tag. Evidence: a checker enumeration of every schema/props read in record-related-list.tsx at 6099dd8 shows zero reads of either, against 10 declared keys read un-cast as the control. The block never passes either to RelatedList, and RelatedList draws its View All footer only when an onViewAll prop is passed, which this block never passes. CAVEAT: this is a static reading. objectui AGENTS.md requires a runtime SchemaRenderer probe that varies only the key before an inertness card is filed; that probe was NOT run here. Seam: spec:RecordRelatedListProps.showViewAll → renderer:RecordRelatedListRenderer (RelatedList onViewAll never wired) · Seam: spec:RecordRelatedListProps.actions → consumer: none · dedupe: record:related_list showViewAll · related list View All link inert · RecordRelatedListProps actions unread · onViewAll never wired · declared not honoured related list",
"carrier: none (承接者:无) · for the showViewAll/actions finding above; in PR #10303 Acceptance notes, not filed"
]
}
draft · base main · Fixes #9963 · Clause-②: no at line start
the fix
RecordRelatedListRendererProps loses its any index and its Record<string, any> intersection. schema is the mirror, plus optional objectName and the objectstack#6953 dataSource binding, typed by the existing core export. The host props are exactly the ones the component reads, so a misspelled declared key is now TS2551. The three routed keys stay behind their casts, per objectui#8649
pins + ablation
red first on the unchanged renderer (8 errors). Leg A (restore the intersection) gives exactly 5, leg B (restore the index) exactly 2, and the controls stay green. All 8 workspace importers type-check
review-tier record
PASS at 979764a1, posted on the PR
CI
required contexts green. The advisory Spec Main Shape Gate is red repo-wide (objectui#10287), not this PR's
Landing
Held until objectui#10287 (priority:p0, claimed by this seat) lands. Then the PR enters the merge queue.
Out of scope
class a: the same any index shape is live on 9 sibling record:* renderers in @object-ui/plugin-detail: chatter, details, highlights, path, activity, history, quick-actions, reference-rail and alert. ⇒ filed by the seat as one class card, citing this PR as the worked repair.
class b (static only): record:related_list's declared showViewAll / actions have zero reads, and RelatedList draws View All only under an onViewAll that is never passed. objectui AGENTS.md requires a runtime probe first. ⇒ held for a probe; not filed yet.
Acceptance notes: the changeset clause 「now fails to compile」 holds for fresh literals only. Non-blocking.
Activity
objectstack-fleet commentedon Sep 24, 2026
Claim: PM loop round 1 —
domain:uiexecution seatSession:
session_01BA3nKVUwKQJf8DBxrSVtNCBranch:
claude/issue-9963-related-list-props-refusalWorktree:
objectui-issue-9963Domain:
domain:uiSeat:
domain:ui#1File surface:
packages/plugin-detail/src/renderers/record-related-list.tsx(theRecordRelatedListRendererPropsdeclaration and its reads), its tests underpackages/plugin-detail/src/renderers/__tests__/, one.changeset/9963-…md(stop on breach; explain in the report)Container & model:
M,mode:subagent,model: opus(default judgement tier) —dispatch-gates.mjsrefuses for this repo from the objectstack checkout ⇒ no path-derived mandate; tier is this seat's judgement: a published props type whose looseness is partly deliberate.Clause-②: no
Thread-read: none
Serial constraints cleared: every open PR's file list read 2026-09-24T15:53Z (objectui#10285, #10284, #10283, #10282, #10279, #10278, #10273, #10270, #10268, #10264, #10255, #10253, #10169, #9488, #9391, #8941) ⇒ none touches
record-related-list.tsx. objectui#10186 (domain:ui#4) holdspackages/plugin-detail/src/RelatedList.tsx⇒ ⛔ fenced by name. The predecessor objectui#9475 is closed; its PR objectui#9962 is merged.Scope
The card, as filed:
RecordRelatedListRendererProps'schemaintersectsRecord<string, any>and the interface carries[k: string]: any, so a misspelled key type-checks at every read. The card's own ⛔ applies: 「Not simply 『delete the index signature』」. The docblock states why the wrapper is deliberately looser than the mirror (the objectstack#6953 authoring shape). ⇒ keep that looseness only where it is needed, and restore refusal on every declared read. ⇒Fixes #9963.Why
Clause-②: noIt narrows what the props type admits and adds no export or accepted key. ⛔ Stop and report if keeping the objectstack#6953 shape needs a new exported type.
domain:uiseat #1 ·session_01BA3nKVUwKQJf8DBxrSVtNC· claim · 2026-09-24T15:55Zobjectstack-fleet commentedon Sep 24, 2026
os-dev-report
{
"issue": 9963,
"status": "done",
"branch": "claude/issue-9963-related-list-props-refusal",
"pr": "#10303",
"session": "session_01BA3nKVUwKQJf8DBxrSVtNC (mode:subagent, so this is the parent's session; it is the Claude-Session trailer on commit 979764a)",
"premise_still_valid": true,
"summary": "Premise confirmed on origin/main 6099dd8.
RecordRelatedListRendererProps.schemaintersected the mirror with Record[string, any], and the interface carried[k: string]: any. A new pin, compiled against that unchanged renderer, reproduced the card: the misspelled readschema.relationshipValueFeildtype-checked. The mirror control refused the same misspelling in the same command. Repair, in the claimed surface only (record-related-list.tsx, its renderers/tests, one changeset): the schema type is now the mirror minusobjectName, plusobjectNameoptional, plusdataSource?: ElementDataSourceConfig. That type is the gate's own existing export from @object-ui/core, so no new exported type and Clause-2 stays no (the built d.ts shows it). Host props are exactly the ones the component reads: schema, className, style, data-obj-id, data-obj-type. A runtime probe of the real SchemaRenderer over the real registration measured what is forwarded; the registration is typedComponentRenderer[T = any], so the declaration binds typed JSX callers only. Every read was enumerated with the checker. (a) 10 mirror keys, 18 un-cast reads. (b)dataSource, read by the gate, plusobjectNameoptional. (c) requiredPermissions, enforceFieldSecurity and redactFields are real reads through(schema as any)casts, ruled undeclarable by objectui#8649. Their reads are untouched; a TYPED schema literal writing one is now refused with TS2353, pinned as a reading, not re-admitted. No importer broke: plugin-detail plus all 8 workspace importers type-check with 0 errors. The objectui#9475 ledger leg_MisspellingIsStillAdmittedHerewent red as designed; its re-derivation and mirror control moved to the new pin file. Changeset: @object-ui/plugin-detail minor (a published props type narrows; major is banned). The card's NOT MEASURED census is measured: 9 other renderers carry the shape (see findings). The assignee (os-bill, PM's) was not touched; the PM's claim 5817542520 named this branch.","tests": "All at HEAD 979764a, the working tree equal to HEAD (git diff HEAD 0 bytes, 0 untracked). REPRO:
tsc -p tsconfig.test.jsonin packages/plugin-detail with the new pin against the UNCHANGED renderer at 6099dd8 gave exit 2 and 8 errors, all in the new file: TS2578 on the misspelled schema read, the misspelled host prop and the 3 cast-key literals; TS2344 on the exact key-set leg, the dataSource-type leg and the host key-set leg. Controls green in that command: the mirror misspelling, the authoring shape{ relationshipField, dataSource: { object, view } }, the full binding, all 12 mirror members, and each mirror member at its own type. AFTER:pnpm --filter @object-ui/plugin-detail run type-check(tsc --noEmit plus tsc -p tsconfig.test.json) exit 0, 0 errors.--listFilesshows 201 test files compiled (200 tracked plus the new one). The codes behind the directives were read from a copy with the directives stripped: TS2551 'Did you mean relationshipValueField' on the schema read, TS2551 'Did you mean className' on the host prop, TS2353 x3 on the cast keys. VITEST from the repo root:pnpm exec vitest run packages/plugin-detail/gave Test Files 200 passed, 1 skipped (201) and Tests 2005 passed, 8 skipped. The two touched files alone gave 13/13. IMPORTERS: built the union dependency closure (35 packages, VERDICT command-exit 0), then ranpnpm --filter X run type-checkfor plugin-calendar, plugin-gantt, plugin-grid, plugin-kanban, plugin-tree, example-console-starter, app-shell and console. All 8 gave exit 0 with 0 errors, and each log echoes the script name. ABLATION, through objectstack scripts/ablation-replace.mjs (a literal anchor that must hit, blob hashes, restore via git checkout HEAD, trap-armed), wrapped aroundtsc -p tsconfig.test.json. Leg A put& Record[string, any]back on schema: anchor 1 to 0, replacement 0 to 1, blob b97d2f7c2640 to 38afd1d37cfd, on-disk grep 1. It gave exactly 5 errors: the misspelled read (TS2578), the key-set leg (TS2344) and the 3 cast-key legs (TS2578). The authoring-shape, full-binding, all-mirror-members, dataSource-type, objectName and host legs and the mirror control stayed green. Restored: blob == HEAD b97d2f7c2640, git diff HEAD empty. Leg B put[k: string]: anyback on the props interface. It gave exactly 2 errors: the host key-set leg (TS2344) and the misspelled host prop (TS2578). Everything else stayed green. Restored: blob == HEAD, diff empty. The first leg-B attempt was REFUSED by the tool before any command ran: the replacement contained the anchor, so its count could not fall. It is a no-op, not a reading; the retry used a non-overlapping replacement. No build or dist leg was needed: the pins import the renderer by relative SOURCE path, and the subject is type-level, read by tsc from source. The vitest runtime legs are type-erased and were not re-run under the ablation. GATES, exit 0: check:control-bytes, check:new-line-citations (VERDICT 0 new citations), node scripts/check-changeset-presence.mjs (1 changeset declared), check:element-data-source-declaration, check:component-surface-parity, check:handler-key-reads, check:comment-mask-corpus, check:test-path-roots, check:vi-mock-specifiers, check:vi-mock-inherit, check:vi-mock-override-shape, check:changeset-claims, check:pending-changeset-literals, check:phantom-deps, check:installed-pin-claims, check:published-tsconfig-exclude. NOT MEASURED: check:sdui-registration-pins (exit 2, needs a console bundle) and check:readme-exports (population collapsed, needs every package built). Both are PREREQUISITE NOT MET, not failures, and neither reads a file this diff touches. Remote CI is also NOT MEASURED; this is handed over before CI converges. ESLINT, narrowed and declared. (1) Population: the 3 touched .ts/.tsx files; the changeset is not linted. (2)--format jsoncounted 3 files, 0 errors, 34 warnings, all no-explicit-any plus 1 react-refresh; the renderer went from 24 to 22 warnings. (3) eslint.config.js has 0 projectService / project: against 9 rules: and 9 files:, so there is no type-aware linting and the diff cannot move an untouched file's verdict. The repository-widepnpm lintis CI's run. FORWARDING PROBE (throwaway, not committed): real SchemaRenderer, registration swapped for a spy. Forwarded props were aria, className, data-obj-id, data-obj-type, disabled, id, limit, properties, relationshipField, title, and schema (keys aria, className, dataSource, id, limit, properties, relationshipField, title, type).","mcp_calls": "0. No MCP tool was called.",
"api_writes": "2 REST writes, both through the fleet-write relay as objectstack-fleet[bot]. (1) POST /repos/objectstack-ai/objectstack/dispatches, whose relay run 36029047140 executed POST /repos/objectstack-ai/objectui/pulls (draft) and opened #10303. (2) POST /repos/objectstack-ai/objectstack/dispatches, executing POST /repos//issues/9963/comments (this os-dev-report). One earlier pr_create attempt was REFUSED by write-pace (exit 10, fleet token budget 40/40) before anything was sent, so it made 0 writes. It was re-sent once after a slot freed. git push x2 (the empty-branch probe and 979764a) are not REST. 0 label writes, 0 PATCH, and the PR body was written once.",
"open_questions": [],
"out_of_scope_findings": [
"class: a · The #9963 defect is live on 9 sibling record:* renderers in @object-ui/plugin-detail; none is touched here. Failing probe: a throwaway
tsc -p tsconfig.test.jsonat 979764a put one @ts-expect-error per renderer. A misspelled DECLARED schema member is ADMITTED (TS2578 unused) on 8: record-activity types, record-chatter position, record-details hideFields, record-highlights fields, record-history entries, record-path statusField, record-quick-actions actions, record-reference-rail entries. A misspelled host propclassnameis ADMITTED on all 9, those 8 plus record-alert. Lit controls in the same run: record-alert's schema, which has no index, refused; record-related-list, repaired here, refused both. Census: an AST walk at 6099dd8 over 57 non-test sources and 44 *Props declarations, with enumeration and reads from that one commit. 10 carry an any string index, #9963's own included; 34 carry none. By form: 4 exact mirror-intersection (chatter, details, highlights, path); 4 an index inside an inline schema literal (activity, history, quick-actions, reference-rail); 1 outer-only (alert). Each may carry deliberate looseness like #9963's docblock did, so each owes the same per-read (a)/(b)/(c) measurement, not a blanket delete. Suggested as ONE follow-up card for the class, citing #9963 as the worked repair. dedupe:Record string any index signature renderer props·misspelled key type-checks record renderer·RendererProps index signature plugin-detail·record-details schema Record string any·sibling renderers props looseness","carrier: none (承接者:无) · for the sibling class above; noted in PR #10303, not filed",
"class: b ·
showViewAllandactionson record:related_list are declared and published, but this block honours neither. Contract text, from @objectstack/spec 17.4.0 as installed: RecordRelatedListProps.showViewAll 'Show "View All" link to see all related records'; RecordRelatedListProps.actions 'Action IDs available for related records'. Both are also on the mirror RecordRelatedListComponentProps and among @object-ui/plugin-detail's registry inputs for this tag. Evidence: a checker enumeration of every schema/props read in record-related-list.tsx at 6099dd8 shows zero reads of either, against 10 declared keys read un-cast as the control. The block never passes either to RelatedList, and RelatedList draws its View All footer only when anonViewAllprop is passed, which this block never passes. CAVEAT: this is a static reading. objectui AGENTS.md requires a runtime SchemaRenderer probe that varies only the key before an inertness card is filed; that probe was NOT run here. Seam: spec:RecordRelatedListProps.showViewAll → renderer:RecordRelatedListRenderer (RelatedList onViewAll never wired) · Seam: spec:RecordRelatedListProps.actions → consumer: none · dedupe:record:related_list showViewAll·related list View All link inert·RecordRelatedListProps actions unread·onViewAll never wired·declared not honoured related list","carrier: none (承接者:无) · for the showViewAll/actions finding above; in PR #10303 Acceptance notes, not filed"
]
}
objectstack-fleet commentedon Sep 24, 2026
✅ ACCEPT — PR objectui#10303 at
979764a1· landing waits on objectui#10287domain:uiseat #1,session_01BA3nKVUwKQJf8DBxrSVtNC. I read the report in full and reviewed it against the diff, the tree and CI.main·Fixes #9963·Clause-②: noat line startRecordRelatedListRendererPropsloses itsanyindex and itsRecord<string, any>intersection.schemais the mirror, plus optionalobjectNameand the objectstack#6953dataSourcebinding, typed by the existing core export. The host props are exactly the ones the component reads, so a misspelled declared key is now TS2551. The three routed keys stay behind their casts, per objectui#8649979764a1, posted on the PRSpec Main Shape Gateis red repo-wide (objectui#10287), not this PR'sLanding
Held until objectui#10287 (
priority:p0, claimed by this seat) lands. Then the PR enters the merge queue.Out of scope
anyindex shape is live on 9 siblingrecord:*renderers in@object-ui/plugin-detail: chatter, details, highlights, path, activity, history, quick-actions, reference-rail and alert. ⇒ filed by the seat as one class card, citing this PR as the worked repair.record:related_list's declaredshowViewAll/actionshave zero reads, andRelatedListdraws View All only under anonViewAllthat is never passed. objectui AGENTS.md requires a runtime probe first. ⇒ held for a probe; not filed yet.domain:uiseat #1 · review · 2026-09-24T17:22Zfix(plugin-detail): the related-list renderer's props type refuses a …