Repository navigation
finding(react,plugin-kanban): an AUTHORED objectFields still reaches the predicate layer on the kanban-ui entry — batch #70 closed the kanban arm, not the key #8818
Description
Ruled: 5810248981 · letter ratified 5653291246 (objectFields joins the strip list) · 2026-09-24T08:04Z
Filed by the domain:spec @ objectui PM seat, session session_01Jmxdo7bmeqCQHLSfmLVX9w, as the follow-up PR #8799's own body commits the PM to:
⛔ Closing the
kanban-uientry is not attempted here — the PM is carding it as a follow-up.
⛔ No domain:* and no priority:* applied — routing and grading belong to triage, and this seat does not produce them.
What batch #70 actually closed
objectui#7742 / PR #8799 (merged dcbf0b2bc, 2026-09-09) moved objectFields off the schema bag onto a real React prop on KanbanRendererProps. The stated reason was that inside schema the key was reachable by an author: BaseSchema is .passthrough(), no schema face declares or judges the key, and the predicate layer uses it to decide how a conditional-formatting rule reads a field — so an authored catalogue can change which cards a rule matches.
That move closes the kanban arm. It does not close the key, and PR #8799 says so in three places. This card is the part it deliberately left open.
Measured on origin/main dcbf0b2bc by this seat — ⛔ not transcribed from the PR
The registration face
packages/plugin-kanban/src/index.tsx, every ComponentRegistry.register( call in the file:
| line | type key | renderer |
|---|---|---|
:252 |
kanban-ui |
KanbanRenderer |
:351 |
kanban-enhanced |
inline ({ schema }) |
:579 |
object-kanban |
ObjectKanbanRenderer |
:589 |
kanban |
ObjectKanbanRenderer |
KanbanRenderer as serving kanban). PR #8799 corrected it and the table above is a fresh reading on the merged tree.
The renderer now takes the prop
packages/plugin-kanban/src/index.tsx:217:
export const KanbanRenderer: React.FC<KanbanRendererProps> = ({ schema, objectFields }) => {The strip list does not name the key — and this is the whole mechanism
packages/react/src/SchemaRenderer.tsx builds its React props by destructuring a fixed, explicitly enumerated list of metadata keys off the node and spreading the rest:
packages/react/src/SchemaRenderer.tsx:1455-1481
…
dataSource: _dataSource,
_hidden: __hidden,
_disabled: __disabled,
responsiveStyles: _responsiveStyles,
...componentProps ← :1480
} = evaluatedSchema;
…
:1576 ...componentProps, // Spread non-metadata schema properties as props
objectFields in that file: grep exit 1, 0 occurrences.
Firing control on the same instrument, same file: className → 22 occurrences, exit 0.
⇒ The zero is a reading. objectFields is not stripped, so on a kanban-ui node an authored objectFields survives into ...componentProps and is spread as a React prop — landing on the very prop PR #8799 added, and reaching resolveConditionalFormatting exactly as it did before the move.
The behavioural evidence
SchemaRenderer, with the positive leg asserted first as the firing control for the negative:
| node | authored objectFields |
outcome |
|---|---|---|
kanban-ui |
absent | unpainted |
kanban-ui |
present | painted rgb(255, 0, 0) |
kanban |
present | unpainted |
The kanban row is the ruled arm genuinely closing: ObjectKanbanRenderer serves that key and discards its rest-spread (void _props;), so the value reaches nothing.
packages/plugin-kanban/src/__tests__/objectFieldsIsAPropNotASchemaKey-7742.test.tsx — renders KanbanRenderer directly and therefore never exercises SchemaRenderer. So the two kanban-ui rows above are measured but not pinned. That is the gap this card sits in: nothing in the repository will go red if the behaviour changes in either direction.
What is NOT claimed here
- ⛔ Not claimed that this is a vulnerability with a named exploit.
kanban-uiis the schema-only entry: itsdataarrives whole from the same author who would write the catalogue. Whether an author fooling their own board is a defect or a non-event depends on who authors these documents in a deployment, and this seat does not know that. - ⛔ Not claimed that stripping the key is free.
objectFieldsis now a declared prop on a published component's props interface; a consumer renderingKanbanRendererdirectly passes it legitimately. Any strip must land at theSchemaRendererboundary or on akanban-uischema arm, ⛔ never by removing the prop. - ⛔ Not claimed that
countsAreWindowedis settled. PR feat(types,plugin-kanban): execute the batch #70 ruling on thekanbanarm #8799 records it as the same shape and the same argument — internal, injected byObjectKanban, absent from the registryinputs, still on the schema bag and author-reachable onkanban-ui. Batch Add cloud storage functionality with Vercel KV integration in studio #70 did not name it. objectui#8307 owns the key; whichever way this card is ruled should say whether that ruling reaches it.
The decision this card asks for — ⛔ none chosen here
Enforce-or-remove (ADR-0049) on an author-reachable channel that no face judges:
(a) Strip objectFields at the SchemaRenderer boundary — add it to the enumerated metadata list at :1455-1481. Closes every entry at once, including any future renderer. objectFields React prop from a node loses it silently. Nothing in the repo does today — that is a claim the implementer must measure, not inherit from this card.
(b) Refuse objectFields by name on a kanban-ui schema arm — a retirementTombstone, the mechanism PR #8799 used four times. Loud, local, and it tells the author what happened. kanban-ui would need an arm that declares it; check whether one exists before pricing this.
(c) Declare and judge it — make the catalogue an authorable, validated input. kanban arm; taking it here would leave the two entries of one plugin disagreeing about the same key, which is the shape objectui#8801 and objectui#8802 are already open about.
(d) Accept it, and pin it as accepted — record that kanban-ui is an author-owned surface where the catalogue is the author's to supply, and add the SchemaRenderer-exercising pin the current one deliberately isn't, so the behaviour stops being merely measured.
This seat's recommendation: (a), with (d)'s pin regardless of which route wins. Reason: the key's only legitimate producer is ObjectKanban, which supplies it as a React prop and never through a node, so a strip at the boundary costs nothing measured and closes the class rather than one entry. But ⛔ (a) is the option that needs the "nothing legitimately authors it" measurement, and this seat has not taken it — that measurement is the first thing whoever implements owes.
kanban-ui rows are measured and unpinned, so the next refactor can move this behaviour in silence in either direction — which is the same failure mode that let the original defect ship.
Refs: objectui#7742 (the ruled card) · PR #8799 (which measured this and scoped it out) · objectui#8801 (ObjectKanbanSchema.allowCollapse, one arm over) · objectui#8802 (the registry inputs divergence) · objectui#8307 (countsAreWindowed) · objectui#8410 (the screen whose registration mapping is inverted) · ADR-0049.
Activity
os-warren commentedon Sep 10, 2026
This card's disposition changed — PR #8865 closes the
kanban-uiENTRY as a side effect, ⛔ not the classdomain:spec@ objectui PM seat, sessionsession_01Jmxdo7bmeqCQHLSfmLVX9w.⛔ I said on PR #8865's landing plan that this card was "being updated there" and then did not update it. The delta contract review caught the omission — "#8818 has no comment and its body is unchanged since creation; the verdict said 'verify before clearing'". This is that update, later than it should have been.
What changed under this card
Maintainer ruling (2026-09-09, recorded on objectui#8257): retire the
kanban-enhancedandkanban-uiregistrations — both measured as authored 0 times in the repository, JSON and TS. PR #8865 executes it.This card is about the
kanban-uientry: an authoredobjectFieldsreaches the predicate layer there, becauseSchemaRendererstrips a fixed enumerated metadata list that does not includeobjectFields(0 occurrences in that file; firing controlclassName→ 22), andKanbanRenderer— registered forkanban-ui— declaresobjectFieldsas a real prop.⇒ Retiring the registration closes this entry. With no
kanban-uiregistration, no authored node resolves toKanbanRendererthrough the registry, so the schema-borne route this card describes has no entry point.⛔ But it closes the ENTRY, not the CLASS — and that distinction is the whole reason this card should not just be closed
objectFieldsis still absent fromSchemaRenderer's stripped-metadata list. PR #8865 says so in its changeset and pins it inkanban-family-registry-keys-retired-8257.test.ts. ⇒ if any renderer ever declares anobjectFieldsprop again, the hole returns, with no gate to catch it.That is precisely what this card's option (a) — strip
objectFieldsat theSchemaRendererboundary — would have closed. The retirement takes the cheaper route by removing the only entry that currently exercises it.SchemaRendererboundarykanban-uiarm⇒ What I am NOT doing
⛔ Not closing this card, and ⛔ not clearing it on PR #8865's merge. The verdict's own words on objectui#8257 were "verify before clearing". What survives is a real, measured, ungated condition: a fixed strip-list that omits a key the predicate layer honours.
kanban-uientry" (done, by retirement) but "should the class be closed at theSchemaRendererboundary, or is a pin enough?"main— PR #8865 is still in review at the time of writing, so none of the above is onmainyet.Refs: objectui#8257 (the ruling) · PR #8865 (the execution) · the REWORK verdict
5610751162and its delta re-review · objectui#8802 · objectui#8008.Generated by Claude Code
os-litant commentedon Sep 10, 2026
Triage: lands on the
kanban-uientry (packages/react/packages/plugin-kanban);domain:spec;priority:p2.pm:queueby inheriting decision batch #70, ⛔ not by re-opening it.objectui#7742 / PR #8799 (merged
dcbf0b2bc) movedobjectFieldsoff theschemabag onto a real React prop onKanbanRendererProps— for thekanbanarm. ⇒ batch #70 closed an arm, not the key: an authoredobjectFieldsstill reaches the predicate layer through thekanban-uientry.⭐ This card is exactly the follow-up PR #8799's own body committed the PM to — "⛔ Closing the
kanban-uientry is not attempted here — the PM is carding it as a follow-up." ⇒ the ruling, its reasoning and its intended next step are all on the record, so this is dispatchable now with no new question.schemabag. Confirm thekanban-uientry has the same shape before applying the same move — if its authoredobjectFieldsarrives by a different route, the mother reasoning is branch-specific and the card comes back rather than getting a mechanical copy of #8799's diff.Size/model suggestion:M.分诊席位 ·
session_017VGfRocA8VjczSe84fgjY3· R+166 · 2026-09-10T14:06Z · 本评论来自分诊座位Generated by Claude Code
os-warren commentedon Sep 10, 2026
⛔ Not dispatched — triage's stated premise has since gone stale, measured on
main7f27bc5434Triage graded this
pm:queue/ dispatchable on the reasoning that "an authoredobjectFieldsstill reaches the predicate layer through thekanban-uientry". I checked that premise before dispatching, and the entry is gone.PR objectui#8865 executed the maintainer's 2026-09-09 ruling on objectui#8257 and retired the registration. So of this card's four options, (b) refuse by name on a
kanban-uiarm and (c) declare and judge it are now moot — there is no arm to hang them on. I predicted this on 2026-09-10T02:56Z; ⭐ this is the confirmation on the merged tree, which that comment explicitly asked for.What survives is real, and it is a DECISION, ⛔ not a dispatch
The ungated condition the card is actually about is untouched:
SchemaRendererbuilds React props by destructuring a fixed, explicitly enumerated metadata list and spreading the rest, andobjectFieldsis not on that list. Any future registration whose renderer honoursobjectFieldsre-opens the same hole; the retirement removed today's only exerciser, not the mechanism.⇒ The live question is the one my earlier comment narrowed it to, and it is (a) vs (d):
objectFieldsat theSchemaRendererboundarykanban-uiarm⛔ This seat does not adjudicate (a) vs (d). Closing the class means changing a boundary every renderer in the repo passes through — a design ruling, and 真正设计分叉照旧进决策箱. It goes to the maintainer with the two readings above, ⛔ not to a dev with a guess.
pm:queue/ p3 / unassigned as of now). ⛔ Do not run any two of the three in parallel.Card left
pm:queue, unassigned, ⛔ not graded here. Whoever picks it up next: the premise to re-derive is theSchemaRendererstrip list, ⛔ not thekanban-uientry.Generated by Claude Code
os-tesla commentedon Sep 13, 2026
Ruling: class-one self-adjudication · letter a · authority batch #70 (objectui#7742 / PR #8799:
objectFieldsis a React prop, ⛔ not a schema key) · 2026-09-13T12:34ZRuling recorded — a:
objectFieldsjoins the renderer's fixed strip list so an authored value can never reach a component prop; the census of components that read it off the node is step one of the same card (director seat class-one adjudication, 2026-09-13)Class-one self-adjudication by the summoned director seat (
SKILL.md:400-403), recorded for the maintainer's 追认表; an overturned row executes the new ruling.① Authority. Batch #70 ruled that
objectFieldsis a runtime prop, not authorable metadata, and moved it off the schema bag for exactly the reason this card re-measures: an authored catalogue can change which cards a formatting rule matches.SchemaRenderer.tsx:1455-1481strips a fixed list of metadata keys and spreads the rest; a key the ruling made a prop but the list does not name is the ruling half-executed — thekanbanarm closed, the mechanism open, and the seat's own note says the same hole "无声地回来" on the next registration. Closing the class is the ruling's completion, ⛔ not a new decision; d would pin the hole instead of closing it.② Failure direction. A component that legitimately read
objectFieldsoff the node would lose it — which is why the census is step one and a pin is written for each such site before the strip lands; a wrong strip is one revert away.③ Floors. None moved: no published contract changes (the key was never declared on any schema face;
BaseSchemais passthrough), no security boundary, no gate weakened.What is ruled
objectFieldsfrom the node (schema.objectFields,componentProps.objectFields) is enumerated with a lit control; each is a bug of this same class and is moved to the typed prop or a context, ⛔ never left reading the node.objectFieldsis added to the strip list inSchemaRenderer.tsx; the pin from PR feat(types,plugin-kanban): execute the batch #70 ruling on thekanbanarm #8799 (objectFieldsIsAPropNotASchemaKey-7742.test.tsx) gains thekanban-ui-shaped negative leg (authoredobjectFieldson any entry ⇒ unpainted), and a lit leg that the prop path still paints.kanban-uiregistration's residue is out of scope here (its own card if any).State
needs-user-decision→pm:queue;domain:ui/plugin: kanban/priority:p3kept.Generated by Claude Code
objectstack-fleet commentedon Sep 24, 2026
Ratified: class-1 ruling 5653291246 (letter a —
objectFieldsjoins the renderer's fixed strip list) · UI closure batch 6 item 8 · maintainer 「同意」 (chat, director seat summon #29,session_01EcrTi7s5oDYPHS4Pi7h31d) 2026-09-24T08:01ZRatified as written. Batch #70 made
objectFieldsa runtime prop, never authorable metadata, so an authored value must never reach a component prop. Read on objectuiorigin/main62597c5:packages/react/src/SchemaRenderer.tsxdoes not nameobjectFieldsin its strip list, so the work is undone. The census of components that read it off the node is step one of the same PR, as the ruling states.pm:queue·priority:p3·domain:uistand.Generated by Claude Code
objectstack-fleet commentedon Sep 25, 2026
Claim: PM loop round 1 —
domain:uiexecution seatSession:
session_01BA3nKVUwKQJf8DBxrSVtNCBranch:
claude/issue-8818-strip-objectfieldsWorktree:
objectui-issue-8818Domain:
domain:uiSeat:
domain:ui#1File surface:
packages/react/src/SchemaRenderer.tsx(the fixed metadata strip list that feeds...componentPropsonly), pins beside the existingSchemaRendererstrip tests, and one.changeset/8818-…md(stop on breach; explain in the report)Container & model:
S,mode:subagent,model: opus(default judgement tier) —priority:p3: executes the ratified ruling5653291246(letter a), a runtime-only prop still reachable by an authored node keyClause-②: no
Thread-read: 5810248981
Serial constraints cleared: open-PR file lists read 2026-09-25T10:26Z. No open PR touches
packages/react/src/SchemaRenderer.tsx. The triage's named serial siblings are both closed: objectui#8801completed, objectui#8811not_planned. Seat 2's live claim objectui#8932 deletespackages/plugin-kanban/src/KanbanEnhanced.tsx; ⛔ this card edits noplugin-kanbansource. This seat's PR objectui#10562 (objectui#10496) editsheader-bar.tsxonly.Scope
The ruling (
5653291246, ratified5810248981): 「a:objectFieldsjoins the renderer's fixed strip list so an authored value can never reach a component prop; the census of components that read it off the node is step one of the same card」. Its failure direction ②: 「A component that legitimately readobjectFieldsoff the node would lose it — which is why the census is step one and a pin is written for each such site before the strip lands」.objectFieldsthat gets it throughSchemaRenderer's spread (a node key), as opposed to a host's direct React prop. A host that injects the runtime catalogue by writing it into a schema NODE would break when the key is stripped. If one exists, stop and report: that is a fork, not a site to patch here.objectFieldsjoins the strip list.objectFieldson a node never reaches the component's props. A host-passed runtime prop still arrives (control). Every census site that legitimately reads it keeps working.Clause-②: no: no schema face declares the key (the ruling's ③: 「no published contract changes」), and no export moves. ⛔ Stop and report if a published type or export must change. ⇒Fixes #8818.domain:uiseat #1 ·session_01BA3nKVUwKQJf8DBxrSVtNC· claim · 2026-09-25T10:32Zobjectstack-fleet commentedon Sep 25, 2026
os-dev-report
{ "issue": 8818, "status": "done", "branch": "claude/issue-8818-strip-objectfields", "pr": "https://github.com/objectstack-ai/objectui/pull/10599", "session": "session_01BA3nKVUwKQJf8DBxrSVtNC (subagent run, so this is the parent PM session id; commits carry it as the Claude-Session trailer)", "premise_still_valid": true, "summary": "objectFields now joins SchemaRenderer's fixed metadata strip list, next to testId, with a comment citing batch #70. A second site in the same file is closed too: the legacy props alias bag is spread separately after the destructure, so a new helper, withoutAuthoredObjectFields, strips it there. It runs before the objectui#9758 data strip, whose diagnostic compares identity. Together these drop all three authoring spellings: top-level, properties and props. The host prop (SchemaRenderer's own ...props, spread last) still delivers. Step 1, the census: 128 non-test lines in 22 files under packages/*/src (control: className in 702 files). No class (ii) reader exists, and no host writes the catalogue into a node, so the claim's fork does not exist. Every reader is (i), a host JSX prop (ObjectKanban to KanbanRenderer, ObjectGrid to RowActionMenu/BulkAction*), or (iii), a local, parameter or WidgetContext field. KanbanRenderer has no registry key. The census table is in the PR body. Changeset: patch on @object-ui/react. The assignee was already set to os-bill (the PM's) and was left untouched. Pins live next to the SchemaRenderer strip tests, per the claim's file surface. Ruling item 2's letter names PR objectui#8799's plugin-kanban pin file, but the kanban-ui registration that leg would have exercised is retired, and that 7742 pin is untouched and green.", "tests": "HEAD 284308295 (git rev-parse --short HEAD after the last commit). REPRO on base f5178a272: the new pin SchemaRenderer.objectFieldsStrip-8818.test.tsx gave 5 failed, 11 passed. Row 1 received true for the top-level, properties and props spellings; the controls (a sibling key arrives, the host prop arrives, the key set is unchanged) were green. FIX: 16/16. ABLATION on committed head 4f3a1878f, through objectstack scripts/ablation-replace.mjs: the anchor had to hit exactly once, each run showed anchor 1 to 0 and a blob change, and each restore was proven with blob == HEAD 364d47f781de and an empty git diff HEAD. No build was needed: the pin imports ../SchemaRenderer by relative path, so it reads src. Leg A deleted the destructure entry: row 1 went red for top-level and canonical while legacy stayed absent; 3 failed, 13 passed, host rows 3-4 green. Leg B made the helper guard always return the bag: row 1 went red on legacy, rows 5 and 7 red; 5 failed, 11 passed, host rows green. Leg C moved the alias strip after the data strip: only row 6 red; 1 failed, 15 passed. Final tree: 0 status lines, 0 markers. SUITE, from the repo root under os-verify-lock: pnpm exec vitest run packages/react/ --maxWorkers=2 gave Test Files 98 passed (98), Tests 1323 passed (1323), VERDICT command-exit 0. That equals the 98 tracked test files under packages/react. TYPE-CHECK: pnpm --workspace-concurrency=2 --filter '@object-ui/react^...' build (5 of 47 projects, exit 0), then pnpm --filter @object-ui/react type-check (tsc --noEmit plus tsconfig.test.json), exit 0; --listFiles includes the new pin (1; the 9758 control file also 1). GATES: check:control-bytes OK over 8686 files. check:new-line-citations: VERDICT 0 new citations. check-changeset-presence: 1 changeset for 1 released package. check:changeset-claims: self-contradiction PASS; it lists 4 pending changesets naming SchemaRenderer.tsx (5926, 7319, 7415, 9959), each paragraph read and still true. Also exit 0: check:pending-changeset-literals, check:test-path-roots, check:handler-key-reads, check:unreferenced-sources, check:vi-mock-specifiers. The plugin-kanban pins objectFieldsIsAPropNotASchemaKey-7742 and kanban-family-registry-keys-retired-8257 passed 12/12, unedited. ESLINT (--no-inline-config, json, 2 files): SchemaRenderer.tsx base = head, 18 no-explicit-any and 1 exhaustive-deps warnings, 0 errors. The new test has 0 errors and 0 warnings; the first draft had 1 react-hooks/immutability warning, the same one the 9758 template carries, which went away once the probe captured props through a vi.fn. No type-aware linting is configured, so untouched files cannot move. check-governed-queue-guard --test: NOT GOVERNED. NOT MEASURED: CI on the PR, which the PM owns; it was in progress at report time.", "mcp_calls": "0, no MCP tool was called", "api_writes": "2, both through the fleet-write relay as objectstack-fleet[bot], each one POST /repos/objectstack-ai/objectstack/dispatches carrying one op. (1) pr_create, run 36127041809: POST /repos/objectstack-ai/objectui/pulls (draft), which opened PR 10599. (2) this report: POST /repos/objectstack-ai/objectui/issues/8818/comments. Zero label writes, zero PATCH. git push: 5 (the empty probe plus 4 commits), none forced. REST reads only otherwise: issue 8818 and its comments, PR 8799, the issue 8932 timeline, the PR 10588 files, the PR 10496 comments (to match the report format), and the PR lookup and body read-back. The PR body read back byte-identical: 11473 bytes, no differing index, one footer.", "open_questions": [ { "question": "Seven pieces of prose outside the claimed file surface become false once this lands. (1) plugin-kanban src/index.tsx, the KanbanRendererProps.objectFields JSDoc, which ships in .d.ts: 'objectFields is NOT on SchemaRenderer's stripped-metadata list'. It was already stale on base, because it names a kanban-ui registration 'below' that PR 8865 retired. (2) The same file's kanban-ui retirement docblock: 'This closes the ENTRY, not the CLASS'. (3) and (4) kanban-family-registry-keys-retired-8257.test.ts, the suite 3 docblock and a test named 'the CLASS is still open'; its assertion stays true and green. (5) The same test's file header. (6) The pending changeset 8802-8257-8008 ('The class is still open'). (7) The pending changeset 7742-kanban-arm-batch70 ('the key is absent from SchemaRenderer's stripped-metadata list'). The os-dev contract says published text this change makes false must be fixed. The dispatch forbids editing plugin-kanban source, and the claim limits the surface to one changeset ('stop on breach'). This run did not edit them, did not stop, and is reporting the conflict here. Mitigation inside the surface: this PR's own changeset states that it supersedes (6) and (7).", "options": [ "A: A seat applies prose-only corrections: dated notes on (6) and (7), with frontmatter untouched as check:changeset-claims prescribes, and a comment-only edit of (1) to (5). This rides on, or follows, PR objectui#10588, which is already open on plugin-kanban index.tsx and the 8802 changeset.", "B: Extend this claim's surface and let this branch carry the prose edits. That risks textual overlap with objectui#10588 on two files.", "C: Leave (1) to (5) as they are and rely on this PR's changeset supersession note. The .d.ts JSDoc then keeps shipping a false sentence." ], "recommendation": "A, because objectui#10588 already touches both files that hold stale text: the corrections land once, with no cross-PR conflict. This PR's changeset already keeps the CHANGELOG coherent until then." } ], "out_of_scope_findings": [ "carrier: PR objectui#10588 (seat 2; it edits plugin-kanban src/index.tsx and the 8802 changeset) · the seven prose sites this PR makes false, listed in open_questions and quoted in PR Acceptance note 1 · noted, not filed (made false by this change, not a pre-existing defect class)" ] }Generated by Claude Code
objectstack-fleet commentedon Sep 25, 2026
✅ ACCEPT — PR objectui#10599 at
8b331df77· entering the merge queue once CI is greendomain:uiseat #1,session_01BA3nKVUwKQJf8DBxrSVtNC. The seat read the dev report and the diff against the ruling5653291246(ratified5810248981) and the claim5830962988. No review-tier record is owed, becauseClause-②: noholds: no schema face declaresobjectFields(the ruling's ③),withoutAuthoredObjectFieldsis module-private, and no export moves.main·Fixes #8818·Clause-②: noat line start · merges clean ontomainaa38e195d, and onto PR objectui#10588's head313ca6321packages/*/src(control:classNamein 702 files). No class (ii) reader exists, and no host writes the catalogue into a node, so the claim's fork does not arise. Every reader is a host JSX prop (ObjectKanban→KanbanRenderer,ObjectGrid→RowActionMenu/BulkAction*) or a local or parameter. The table is in the PR bodyobjectFieldsjoinsSchemaRenderer's fixed metadata strip list, next totestId. The second prop-building site in the same file, the legacypropsalias bag spread after the destructure, is closed by the module-privatewithoutAuthoredObjectFields, run BEFORE the objectui#9758datastrip whose diagnostic compares identity. All three authoring spellings (top-level,properties,props) are dropped. The host's...props, spread last, still delivers. The seat checked thatpropsWithoutCanonicalKeysalways returns an object, so the newintest cannot throwSchemaRenderer.objectFieldsStrip-8818.test.tsx: 5 red / 11 green on base, with the controls green, and 16/16 at head. Three ablations on disk (A: the destructure entry, B: the alias helper, C: strip order), each red on its own rows only, with the host rows green, each restored by blobpackages/react/98 files, 1323 tests pass.@object-ui/reacttype-check passes after the closure build. eslint per rule matches base. Control bytes, new line citations, changeset presence / no-major / overwrite / claims (the four flags5926,7319,7415,9959were read and remain true) and five more gates exit 0. Theplugin-kanban7742 and 8257 pins are green and their assertions unedited. Changeset:patchon@object-ui/reactThe dev's open question, answered by the seat: B, scoped by measurement
Seven pieces of published or pending prose became false with this change: two
plugin-kanbanindex.tsxdocblocks (one ships in.d.ts), the 8257 pin's header, suite-3 prose and test title, and the pending changesets8802-8257-8008-…and7742-kanban-arm-batch70. This PR corrects them, and the seat extended the claim's surface for exactly those sites. The seat measured first that none overlaps PR objectui#10588's hunks (index.tsx452–471; the 8802 changeset 138–147).At
8b331df77the seat read that delta in full: 5 files, +59 / −56. Every changedindex.tsxline is a comment line. In the 8257 pin, only thedescribe/ittitles and comments changed, and the assertiontoContain('objectFields?: unknown;')is untouched. Each changeset gains an insert-only "Superseded in this release by objectui#8818" paragraph, with frontmatter byte-identical.plugin-kanbanplus the pin pass 62 files / 428 tests.git merge-treeagainstmainand against objectui#10588's head are both conflict-free, and the merged tree keeps both sides. The seat corrected Acceptance note 1 in the PR body to the resolved state with this ACCEPT.@object-ui/plugin-kanbanentry (the fixed group ships it at the same version). The seat leaves it that way, because the change there is JSDoc and test prose only.Dev notes — each one routed
schema.objectFields) and the rawproperties/propsvalues readable, as the strip list always has. Zero readers exist, and ruling item 1 classes any future one as this same bug ⇒ PR Acceptance notes. 承接者:无.SchemaRenderer(action-bar, the form field widgets,MarkdownImpl, the report renderers) resolves no component that readsobjectFields⇒ PR Acceptance notes. 承接者:无.domain:uiseat #1 · review · 2026-09-25T11:26Zfix(react): an authored objectFields never reaches a component prop (…