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 }}
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
console: React warnings in Studio — <div> inside <p> in the package sheet, Select switching uncontrolled→controlled in the create form #11804
Filing gate ① — product defect with a named location and a reproduction. reach: Studio package sheet and the Records create form.
Who acts on it: objectui triage → the Studio / app-shell owner. ⛔ Not a claim. Found in a manual browser QA pass of Studio on 2026-10-07; filed one card per finding on the maintainer's word: 「你发现的问题全部提交 issue」, and on the one-card-per-finding question 「覆盖规则,逐条立卡」.
What happens
Package info & settings sheet: "In HTML,
cannot be a descendant of
. This will cause a hydration error."
Create record form: "Select is changing from uncontrolled to controlled."
Suggested direction (triage to rule)
Replace the <p> wrapper with a <div>; give the Select a defined initial value.
Environment
objectstack 879bd38c · examples/app-showcase booted with objectstack dev --ui --seed-admin on an isolated port and SQLite file · objectui 179f6fe9 (HEAD; the framework pin .objectui-sha is a58626c8) served by the console's Vite dev server, perf numbers from a vite build of the same commit · Chromium 141 at 1440×900 · signed in as the seeded platform admin admin@objectos.ai unless stated.
Duplicate check
Semantic issue search on objectstack-ai/objectui (open and closed), react warning div descendant of p select uncontrolled controlled: 2 hits (0 open, 2 closed).
Semantic issue search on objectstack-ai/objectui (open and closed), validateDOMNesting div cannot be a descendant of p console warning sheet description: 4 hits (0 open, 4 closed).
Triage: first grade, bug · priority:p3 · domain:ui · area:studio · pm:queue. Direction as the body proposes
Triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-07T17:28Z. ⛔ Not a claim, ⛔ not a dispatch.
Triage: lands in the Studio package sheet's <p> wrapper and the Records create form's Select ⇒ domain:ui; rationale: a Studio or console surface in objectui. Filed from the browser QA pass of 2026-10-07 (objectstack 879bd38c, objectui 179f6fe9); paths re-read on objectui main9990f9e122.
Claim: PM loop round 8
Session: session_01DrKzdPdyLLBW3qpZ4vtk7z
Account: huangyiirene
Branch: claude/issue-11804-react-markup-warnings
Worktree: objectui-issue-11804
Domain: domain:ui
Seat: domain:ui#1
File surface (line numbers on 4e7dd56). Both sites are measured first, and the dev names each file before editing it.
The <div> inside <p>: the Package info & settings sheet, which Studio opens from its package menu (engine.studio.pkg.manage, StudioDesignSurface.tsx:1031). It is expected in packages/app-shell/src/views/metadata-admin/PackagesPage.tsx, around its SheetDescription (about :643) or another <p> that wraps a block element. The markup changes only: the <p> becomes a <div>, or the nested block becomes inline.
The Select that switches from uncontrolled to controlled: in the Records create form. The dev measures which component renders it (a field widget in packages/fields/src/**, or the form renderer) and gives it a defined initial value. No behaviour change.
The tests beside these, and .changeset/11804-*.md.
⛔ Not on it:
Seat 2's objectui#11792 (claim 6049699621): PackageFormDialog.tsx, PackageIdInput.tsx and CreateItemDialog.tsx.
packages/components/src/ui/**, the Shadcn-synced primitives. If the warning comes from a primitive itself, the dev reports instead.
StudioDesignSurface.tsx, beyond reading where the sheet opens.
@object-ui/types, and any package.json.
Any file outside this list: the dev reports it before opening the PR (stop on breach; explain in the report).
Container & model: M, mode:subagent, model: opus (dispatch-gates --tier --repo objectstack-ai/objectui over these paths: no path-derived mandate; default tier)
Clause-②: no
Responsibility: objectui app-shell and the records create form: Studio's package sheet nests a block element inside <p> ("In HTML, <div> cannot be a descendant of <p>"), and the create form's Select switches from uncontrolled to controlled | the platform path is right: valid markup and a controlled Select from its first render | every user who opens the package sheet or creates a record, measured by the filer in the 2026-10-07 QA pass (React's console warnings)
Thread-read: 6043210265
Serial constraints cleared: none blocking.
{
"issue": 11804,
"status": "done",
"branch": "claude/issue-11804-react-markup-warnings",
"pr": "#11879",
"session": "session_01DrKzdPdyLLBW3qpZ4vtk7z",
"premise_still_valid": true,
"summary": "I reproduced both warnings before editing and fixed each at the component that emits it. H1 was partly wrong: the source is the package sheet's 'Pending changes' header, a p element that holds the draft-count Badge (the Badge primitive renders a div), not SheetDescription. It fires only when the package has pending drafts. The header is now a div with the same classes. H2 was also partly wrong: the source is SelectField's single-value branch (field:select, the type every select gets in the object create form), and it fires on the user's first pick in an unseeded select, not when defaults load. SelectField now gives Radix '' for an undefined value whenever the host passes an onChange, so the Select is controlled from its first render. Saved values are unchanged. A host with no onChange (a bare SDUI node) stays uncontrolled, so its control does not freeze after a pick.",
"tests": {
"head": "0fefd45 (every gate, union and ablation below ran on this local HEAD; branch tip on origin = 0fefd45)",
"merge_commit": "1e4bf56 = merge of origin/main cef0eee (contains 5d69133, checked with merge-base --is-ancestor, exit 0) into the branch, per the PM note; no rebase",
"files_changed": [
"packages/app-shell/src/views/metadata-admin/PackagesPage.tsx (header p -> div, same classes)",
"packages/fields/src/widgets/SelectField.tsx (controlValue: null or (undefined and onChange present) -> '')",
"packages/app-shell/src/views/metadata-admin/PackagesPage.pendingHeaderMarkup-11804.test.tsx (new pin)",
"packages/fields/src/widgets/SelectField.controlledFromFirstRender-11804.test.tsx (new pin, 3 hosts)",
".changeset/11804-react-markup-warnings.md (patch: @object-ui/app-shell, @object-ui/fields)"
],
"H1": "Measured first: rendered the real PackageDetailSheet in happy-dom and captured console.error. With 1 draft, React logged 'In HTML, %s cannot be a descendant of %s' (div, p) and '%s cannot contain a nested %s' (p, div). The only p holding a div was the 'Pending changes' header p (classes 'flex items-center gap-2 text-xs font-medium uppercase tracking-wide text-muted-foreground') with Badge variant=secondary inside it. With 0 drafts, nothing was logged. SheetDescription holds only the id text. Studio's Package info and settings item opens the same PackageDetailSheet.",
"H2": "Measured first: ObjectForm in create mode with registerAllFields and an account-shaped schema (industry select with no defaultValue, status select with defaultValue 'prospect'). On mount: no Select warning. After a pick on industry through Radix's hidden native select: console.warn 'Select is changing from uncontrolled to controlled...'. Payload was {status: prospect, name: Acme, industry: finance}. The emitting widget is SelectField (SingleSelectField; trigger testid select-trigger-industry). It passed value undefined to the Radix Select root. Other selects: RecordPickerDialog filter and GridField cell already pass ''. The InlineFieldInput host passes '' and ActionParamDialog passes '?? null'. FieldEditWidget passes the raw value through SelectField, so this fix covers it. The form renderer's BuiltinSelectControl (bare type 'select') logs the same warning on a first pick (measured) and was not changed: see out_of_scope_findings. No shared helper covers both, because toControlValue is also read as 'absent' by the SDUI select renderer's defaultValue and by radio-group.",
"gates": [
"pnpm --workspace-concurrency=2 --filter '@object-ui/app-shell^...' build (29 projects, covers fields^...) -> exit 0 -> 'STEP build app-shell^... exit=0'; lock VERDICT command-exit 0",
"pnpm --filter @object-ui/fields type-check -> exit 0 (tsc --noEmit && tsc -p tsconfig.test.json; --listFilesOnly includes the new pin)",
"pnpm --filter @object-ui/app-shell type-check -> exit 0 (same chain; --listFilesOnly includes the new pin)",
"pnpm exec vitest run --maxWorkers=2 packages/fields/ + 61 cross-package files (every test naming SelectField, select-trigger- or field:select, plus every PackagesPage test) -> exit 0 -> 'Test Files 302 passed | 1 skipped (303)', 'Tests 4780 passed | 7 skipped (4787)'; lock VERDICT command-exit 0 (held 10m03s, run in the background with a foreground tail --pid wait)",
"earlier focused run: 7 files (all SelectField* and PackagesPage* tests) -> 'Test Files 7 passed (7)', 'Tests 46 passed (46)'",
"pnpm check:control-bytes -> exit 0 -> 'check-control-bytes: OK (scanned 7863 tracked text file(s); skipped 85 binary)'",
"pnpm check:new-line-citations -> exit 0 -> 'VERDICT new-cross-file-line-citations: 0 new citation(s), enforcement report-only -> exit 0'",
"pnpm check:changeset-claims -> exit 0 -> 'No pending changeset names a file this change touches.'",
"pnpm check:pending-changeset-literals -> exit 0 -> 'No test source names a pending changeset.'",
"derived from the diff (new test files, src edits): pnpm check:test-path-roots -> exit 0 OK; pnpm check:unreferenced-sources -> exit 0 'Every shipped source file in every covered package is reachable.'; pnpm check:vi-mock-specifiers -> exit 0 OK",
"node scripts/check-changeset-presence.mjs -> exit 0 -> '4 source file(s) of 2 released package(s) changed, and this change declares 1 changeset(s)'; node scripts/check-changeset-no-major.mjs -> exit 0",
"eslint --no-inline-config --format json on the 4 touched tsx files -> exit 0: 4 results, 0 errors, 27 warnings (pre-existing no-explicit-any and hook shapes; 6 'as any' in the new test, matching sibling tests). This is a narrowed run: population = the diff's 4 lintable tsx files, count = 4 read from the JSON, and eslint.config.js declares no parserOptions or projectService (no type-aware linting), so this diff cannot change a verdict on an untouched file. Repo-wide pnpm lint is CI's"
],
"ablation": "Run on committed 0fefd45 via objectstack's scripts/ablation-replace.mjs in WRAP mode, with an outer trap that restores from HEAD by absolute path. M1 (header back to p): anchor 1->0, blob 4b0f2c0 -> 7fe6a46; pin result 1 failed / 1 passed; the failure lists React's 'cannot be a descendant of' and 'cannot contain a nested' errors. M2 (delete the undefined branch): anchor 1->0, blob 1d69c56 -> 1010868; 2 failed / 1 passed; both failures show 'Select is changing from uncontrolled to controlled'; host 3 stays green. M3 (unconditional undefined -> '' with no onChange guard): anchor 1->0, blob 1d69c56 -> 08f1112; 1 failed / 2 passed; the no-onChange host stays on the placeholder after the pick. Every direction matched the prediction. Restore: blob after restore == HEAD blob (4b0f2c0 / 1d69c56) and git diff HEAD empty after each leg and at the end. The first M2 attempt was a no-op (its replacement text was a substring of the anchor, so the tool refused and ran nothing) and its reading is void; it was re-run as a --delete leg.",
"deviations": [
"Both hypotheses corrected (H1: the Pending changes header, not SheetDescription. H2: fires on the first pick of an unseeded select, not when defaults load). Recorded under H1 and H2.",
"Per the PM note, merged origin/main (cef0eee, which contains 5d69133) as merge commit 1e4bf56. Then added one test-only commit 0fefd45 that reorders the H1 pin's assertions so a regression shows React's own nesting error first.",
"Commit trailers use the model-free pair (Claude-Session plus Co-authored-by: Claude), not the harness's model-named trailer, per os-dev and AGENTS.md. The PR body ends with the os-dev session-URL footer rather than the harness's footer.",
"The first M2 ablation leg was a refused no-op; it was re-run as a delete leg (see ablation).",
"BuiltinSelectControl has the same warning and was not fixed. Fixing it would add @object-ui/components to the verification surface (fails bounded-fix condition 4). It is noted in the PR's Acceptance notes.",
"Open-PR overlap read: 9 open objectui PRs (11870 11869 11868 11867 11856 11845 11844 11600 11069); none touches SelectField.tsx, PackagesPage.tsx or form.tsx. Positive control: 23 tsx paths in the same file listing."
]
},
"mcp_calls": "0 (no MCP GitHub tool used, read or write)",
"api_writes": "2: (1) pr_create through the fleet-write relay: POST /repos/objectstack-ai/objectstack/dispatches, executed as POST /repos/objectstack-ai/objectui/pulls (draft forced), created objectui#11879; read-back 8242 bytes sent = 8242 stored, identical. (2) This os-dev-report comment through post-stamped: POST /repos//issues/11804/comments. Also git push to one branch (empty-branch probe plus two pushes; not REST). Zero label or assignee writes. Reads were single REST GETs (card, thread, open PRs and their files, the PR read-back).",
"open_questions": [],
"out_of_scope_findings": [
"carrier:承接者:无 · noted in the PR's Acceptance notes, not filed. Same family as this card: the form renderer's built-in select branch (BuiltinSelectControl, packages/components/src/renderers/form/form.tsx) passes toControlValue(value), which is undefined for an unseeded field, so a first pick on a bare type 'select' form field logs 'Select is changing from uncontrolled to controlled'. Measured in happy-dom through the real form renderer. The fix would be the same shape (?? '' at that call site, not in the shared toControlValue). No public door or real producer was measured (the object create form never reaches it), so it lacks reach: for filing. Dedupe words: built-in select uncontrolled to controlled form renderer · BuiltinSelectControl toControlValue undefined · bare select form field warning"
]
}
domain:ui seat 1 · session_01DrKzdPdyLLBW3qpZ4vtk7z · reviewed against the PR's file list and diff, git merge-tree, its check runs and the dev's report 6051728326, read 2026-10-08T03:45Z.
Shape: draft → main. The first line is Fixes #11804, and Clause-②: no starts a later line.
Scope: 5 files, +319/−9, inside claim 6051109461's surface. Both sites were measured first, and the files were named before editing.
PackagesPage.tsx (+10/−4): the package sheet's Pending changes header <p> becomes a <div> with the same classes.
packages/fields/src/widgets/SelectField.tsx (+30/−5): the control value becomes '' for undefined when the host passes onChange.
Two pins, and one changeset (@object-ui/app-shell and @object-ui/fields patch).
packages/components/src/ui/** is untouched.
Both hypotheses corrected by measurement, accepted:
H1. The emitter is the Pending changes header <p> that holds the draft-count Badge (which renders a <div>), not SheetDescription. It fires only when the package has pending drafts. Studio's Package info & settings opens the same sheet.
H2. The emitter is SelectField's single-value branch (field:select, which every select in the object create form gets). It fires on the first pick of an unseeded select, not when defaults load.
A host that passes no onChange (a bare SDUI node) stays uncontrolled, so its control does not freeze after a pick. That is pinned (ablation M3).
Clause-② re-read: no export, prop or type changes. SelectField's props are unchanged; only the value it hands Radix differs, so display and saved values are unchanged. no holds.
Tests:
Local union on 0fefd45 (with maincef0eee merged in): 302 files and 4780 tests green across packages/fields and every test that names SelectField, select-trigger- or field:select, plus PackagesPage. Both type-checks and the derived check:* set are green.
Ablation, three legs, each in the predicted direction:
M1, the header back to <p>: React's nesting errors return.
M2, the undefined branch removed: "Select is changing from uncontrolled to controlled" returns.
M3, the onChange guard dropped: the bare host freezes on its placeholder.
CI at 0fefd45: converging, none red at this read. The PR is queued when every check completes.
Out-of-scope, noted, not filed: the form renderer's BuiltinSelectControl (bare type: 'select', packages/components/src/renderers/form/form.tsx) logs the same warning on a first pick. It was measured in happy-dom, but no public door was measured (the object create form never reaches it). It is in the PR's Acceptance notes.
Merged through the merge queue at 2026-10-08T04:23:06Z, after it was queued at 2026-10-08T04:06:43Z.
CI on head 0fefd45 before queueing: 40 of 43 check runs passed, and the 3 skipped are the expected ones.
check-governed-merges.mjs: not governed, +319/−9.
Content check:3035948 is one squash commit on parent 99c481d. It changes 5 files, +319/−9, and all 5 are blob-identical to the reviewed head 0fefd45. The whole diff's patch-id matches (be8c9592…).
Card: closed completed by the PR's Fixes. pm:dispatched was removed in the same pass and read back.
On record:
Both emitters were measured before the fix. One is the package sheet's Pending changes header <p> holding a Badge. The other is SelectField's first pick on an unseeded select.
The form renderer's BuiltinSelectControl has the same warning shape, with no measured public door. It is noted in PR objectui#11879's Acceptance notes and not filed.
Activity
objectstack-fleet commentedon Oct 7, 2026
Path: write metadata — Studio renders valid markup | 缺项 | P3
Triage: first grade,
bug·priority:p3·domain:ui·area:studio·pm:queue. Direction as the body proposesTriage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-07T17:28Z. ⛔ Not a claim, ⛔ not a dispatch.Triage: lands in the Studio package sheet's
<p>wrapper and the Records create form'sSelect⇒domain:ui; rationale: a Studio or console surface in objectui. Filed from the browser QA pass of 2026-10-07 (objectstack879bd38c, objectui179f6fe9); paths re-read on objectuimain9990f9e122.<p>wrapper with a<div>Selecta defined initial valueClause-②: no. Patch changeset in objectui.objectstack-fleet commentedon Oct 8, 2026
Claim: PM loop round 8
Session:
session_01DrKzdPdyLLBW3qpZ4vtk7zAccount:
huangyiireneBranch:
claude/issue-11804-react-markup-warningsWorktree:
objectui-issue-11804Domain:
domain:uiSeat:
domain:ui#1File surface (line numbers on
4e7dd56). Both sites are measured first, and the dev names each file before editing it.<div>inside<p>: the Package info & settings sheet, which Studio opens from its package menu (engine.studio.pkg.manage,StudioDesignSurface.tsx:1031). It is expected inpackages/app-shell/src/views/metadata-admin/PackagesPage.tsx, around itsSheetDescription(about:643) or another<p>that wraps a block element. The markup changes only: the<p>becomes a<div>, or the nested block becomes inline.packages/fields/src/**, or the form renderer) and gives it a defined initial value. No behaviour change..changeset/11804-*.md.⛔ Not on it:
6049699621):PackageFormDialog.tsx,PackageIdInput.tsxandCreateItemDialog.tsx.packages/components/src/ui/**, the Shadcn-synced primitives. If the warning comes from a primitive itself, the dev reports instead.area:records,os-support-ai).StudioDesignSurface.tsx, beyond reading where the sheet opens.@object-ui/types, and anypackage.json.Any file outside this list: the dev reports it before opening the PR (stop on breach; explain in the report).
Container & model:
M,mode:subagent,model: opus(dispatch-gates --tier --repo objectstack-ai/objectuiover these paths: no path-derived mandate; default tier)Clause-②: no
Responsibility:
objectui app-shell and the records create form: Studio's package sheet nests a block element inside <p> ("In HTML, <div> cannot be a descendant of <p>"), and the create form's Select switches from uncontrolled to controlled | the platform path is right: valid markup and a controlled Select from its first render | every user who opens the package sheet or creates a record, measured by the filer in the 2026-10-07 QA pass (React's console warnings)Thread-read: 6043210265
Serial constraints cleared:
noneblocking.area:studioin flight: seat 2's objectui#11781, studio(interfaces): the nav rail draws a separator item as an unlabeled disabled row and ignores badge #11791, studio(new package/object): package id is not derived or validated client-side, namespace is immutable and hidden, object identifier preview omits the prefix #11792, studio: duplicate API reads on entry (packages ×3, _drafts ×4, sys_user_preference ×3) — no shared query cache #11797 and console: Monaco loads from cdn.jsdelivr.net; offline/CSP installs fall back to a textarea and log uncaught errors #11800; seat 3's objectui#11786; this seat's objectui#11802 and studio(interfaces): create flows for list views, dashboards, reports and pages in a writable package (ADR-0084), after #11790's nav item types #11823 (PR objectui#11868).PackagesPage.tsx's package sheet.area:records: objectui#11839 (action renderers) holds no form field widget.batch3 working devs, on the maintainer's word in this session's chat (「改为并行派发,batch 3」, 「继续派发」).Why
Clause-②: no: valid markup and a defined initial value. No export, prop,@object-ui/typesmember, accepted input orpackages/i18nkey changes.objectstack-fleet commentedon Oct 8, 2026
os-dev-report
{
"issue": 11804,
"status": "done",
"branch": "claude/issue-11804-react-markup-warnings",
"pr": "#11879",
"session": "session_01DrKzdPdyLLBW3qpZ4vtk7z",
"premise_still_valid": true,
"summary": "I reproduced both warnings before editing and fixed each at the component that emits it. H1 was partly wrong: the source is the package sheet's 'Pending changes' header, a p element that holds the draft-count Badge (the Badge primitive renders a div), not SheetDescription. It fires only when the package has pending drafts. The header is now a div with the same classes. H2 was also partly wrong: the source is SelectField's single-value branch (field:select, the type every select gets in the object create form), and it fires on the user's first pick in an unseeded select, not when defaults load. SelectField now gives Radix '' for an undefined value whenever the host passes an onChange, so the Select is controlled from its first render. Saved values are unchanged. A host with no onChange (a bare SDUI node) stays uncontrolled, so its control does not freeze after a pick.",
"tests": {
"head": "0fefd45 (every gate, union and ablation below ran on this local HEAD; branch tip on origin = 0fefd45)",
"merge_commit": "1e4bf56 = merge of origin/main cef0eee (contains 5d69133, checked with merge-base --is-ancestor, exit 0) into the branch, per the PM note; no rebase",
"files_changed": [
"packages/app-shell/src/views/metadata-admin/PackagesPage.tsx (header p -> div, same classes)",
"packages/fields/src/widgets/SelectField.tsx (controlValue: null or (undefined and onChange present) -> '')",
"packages/app-shell/src/views/metadata-admin/PackagesPage.pendingHeaderMarkup-11804.test.tsx (new pin)",
"packages/fields/src/widgets/SelectField.controlledFromFirstRender-11804.test.tsx (new pin, 3 hosts)",
".changeset/11804-react-markup-warnings.md (patch: @object-ui/app-shell, @object-ui/fields)"
],
"H1": "Measured first: rendered the real PackageDetailSheet in happy-dom and captured console.error. With 1 draft, React logged 'In HTML, %s cannot be a descendant of %s' (div, p) and '%s cannot contain a nested %s' (p, div). The only p holding a div was the 'Pending changes' header p (classes 'flex items-center gap-2 text-xs font-medium uppercase tracking-wide text-muted-foreground') with Badge variant=secondary inside it. With 0 drafts, nothing was logged. SheetDescription holds only the id text. Studio's Package info and settings item opens the same PackageDetailSheet.",
"H2": "Measured first: ObjectForm in create mode with registerAllFields and an account-shaped schema (industry select with no defaultValue, status select with defaultValue 'prospect'). On mount: no Select warning. After a pick on industry through Radix's hidden native select: console.warn 'Select is changing from uncontrolled to controlled...'. Payload was {status: prospect, name: Acme, industry: finance}. The emitting widget is SelectField (SingleSelectField; trigger testid select-trigger-industry). It passed value undefined to the Radix Select root. Other selects: RecordPickerDialog filter and GridField cell already pass ''. The InlineFieldInput host passes '' and ActionParamDialog passes '?? null'. FieldEditWidget passes the raw value through SelectField, so this fix covers it. The form renderer's BuiltinSelectControl (bare type 'select') logs the same warning on a first pick (measured) and was not changed: see out_of_scope_findings. No shared helper covers both, because toControlValue is also read as 'absent' by the SDUI select renderer's defaultValue and by radio-group.",
"gates": [
"pnpm --workspace-concurrency=2 --filter '@object-ui/app-shell^...' build (29 projects, covers fields^...) -> exit 0 -> 'STEP build app-shell^... exit=0'; lock VERDICT command-exit 0",
"pnpm --filter @object-ui/fields type-check -> exit 0 (tsc --noEmit && tsc -p tsconfig.test.json; --listFilesOnly includes the new pin)",
"pnpm --filter @object-ui/app-shell type-check -> exit 0 (same chain; --listFilesOnly includes the new pin)",
"pnpm exec vitest run --maxWorkers=2 packages/fields/ + 61 cross-package files (every test naming SelectField, select-trigger- or field:select, plus every PackagesPage test) -> exit 0 -> 'Test Files 302 passed | 1 skipped (303)', 'Tests 4780 passed | 7 skipped (4787)'; lock VERDICT command-exit 0 (held 10m03s, run in the background with a foreground tail --pid wait)",
"earlier focused run: 7 files (all SelectField* and PackagesPage* tests) -> 'Test Files 7 passed (7)', 'Tests 46 passed (46)'",
"pnpm check:control-bytes -> exit 0 -> 'check-control-bytes: OK (scanned 7863 tracked text file(s); skipped 85 binary)'",
"pnpm check:new-line-citations -> exit 0 -> 'VERDICT new-cross-file-line-citations: 0 new citation(s), enforcement report-only -> exit 0'",
"pnpm check:changeset-claims -> exit 0 -> 'No pending changeset names a file this change touches.'",
"pnpm check:pending-changeset-literals -> exit 0 -> 'No test source names a pending changeset.'",
"derived from the diff (new test files, src edits): pnpm check:test-path-roots -> exit 0 OK; pnpm check:unreferenced-sources -> exit 0 'Every shipped source file in every covered package is reachable.'; pnpm check:vi-mock-specifiers -> exit 0 OK",
"node scripts/check-changeset-presence.mjs -> exit 0 -> '4 source file(s) of 2 released package(s) changed, and this change declares 1 changeset(s)'; node scripts/check-changeset-no-major.mjs -> exit 0",
"eslint --no-inline-config --format json on the 4 touched tsx files -> exit 0: 4 results, 0 errors, 27 warnings (pre-existing no-explicit-any and hook shapes; 6 'as any' in the new test, matching sibling tests). This is a narrowed run: population = the diff's 4 lintable tsx files, count = 4 read from the JSON, and eslint.config.js declares no parserOptions or projectService (no type-aware linting), so this diff cannot change a verdict on an untouched file. Repo-wide pnpm lint is CI's"
],
"ablation": "Run on committed 0fefd45 via objectstack's scripts/ablation-replace.mjs in WRAP mode, with an outer trap that restores from HEAD by absolute path. M1 (header back to p): anchor 1->0, blob 4b0f2c0 -> 7fe6a46; pin result 1 failed / 1 passed; the failure lists React's 'cannot be a descendant of' and 'cannot contain a nested' errors. M2 (delete the undefined branch): anchor 1->0, blob 1d69c56 -> 1010868; 2 failed / 1 passed; both failures show 'Select is changing from uncontrolled to controlled'; host 3 stays green. M3 (unconditional undefined -> '' with no onChange guard): anchor 1->0, blob 1d69c56 -> 08f1112; 1 failed / 2 passed; the no-onChange host stays on the placeholder after the pick. Every direction matched the prediction. Restore: blob after restore == HEAD blob (4b0f2c0 / 1d69c56) and git diff HEAD empty after each leg and at the end. The first M2 attempt was a no-op (its replacement text was a substring of the anchor, so the tool refused and ran nothing) and its reading is void; it was re-run as a --delete leg.",
"deviations": [
"Both hypotheses corrected (H1: the Pending changes header, not SheetDescription. H2: fires on the first pick of an unseeded select, not when defaults load). Recorded under H1 and H2.",
"Per the PM note, merged origin/main (cef0eee, which contains 5d69133) as merge commit 1e4bf56. Then added one test-only commit 0fefd45 that reorders the H1 pin's assertions so a regression shows React's own nesting error first.",
"Commit trailers use the model-free pair (Claude-Session plus Co-authored-by: Claude), not the harness's model-named trailer, per os-dev and AGENTS.md. The PR body ends with the os-dev session-URL footer rather than the harness's footer.",
"The first M2 ablation leg was a refused no-op; it was re-run as a delete leg (see ablation).",
"BuiltinSelectControl has the same warning and was not fixed. Fixing it would add @object-ui/components to the verification surface (fails bounded-fix condition 4). It is noted in the PR's Acceptance notes.",
"Open-PR overlap read: 9 open objectui PRs (11870 11869 11868 11867 11856 11845 11844 11600 11069); none touches SelectField.tsx, PackagesPage.tsx or form.tsx. Positive control: 23 tsx paths in the same file listing."
]
},
"mcp_calls": "0 (no MCP GitHub tool used, read or write)",
"api_writes": "2: (1) pr_create through the fleet-write relay: POST /repos/objectstack-ai/objectstack/dispatches, executed as POST /repos/objectstack-ai/objectui/pulls (draft forced), created objectui#11879; read-back 8242 bytes sent = 8242 stored, identical. (2) This os-dev-report comment through post-stamped: POST /repos//issues/11804/comments. Also git push to one branch (empty-branch probe plus two pushes; not REST). Zero label or assignee writes. Reads were single REST GETs (card, thread, open PRs and their files, the PR read-back).",
"open_questions": [],
"out_of_scope_findings": [
"carrier:承接者:无 · noted in the PR's Acceptance notes, not filed. Same family as this card: the form renderer's built-in select branch (BuiltinSelectControl, packages/components/src/renderers/form/form.tsx) passes toControlValue(value), which is undefined for an unseeded field, so a first pick on a bare type 'select' form field logs 'Select is changing from uncontrolled to controlled'. Measured in happy-dom through the real form renderer. The fix would be the same shape (?? '' at that call site, not in the shared toControlValue). No public door or real producer was measured (the object create form never reaches it), so it lacks reach: for filing. Dedupe words: built-in select uncontrolled to controlled form renderer · BuiltinSelectControl toControlValue undefined · bare select form field warning"
]
}
Generated by Claude Code
objectstack-fleet commentedon Oct 8, 2026
Review: ACCEPT — PR objectui#11879 (head
0fefd45)domain:uiseat 1 ·session_01DrKzdPdyLLBW3qpZ4vtk7z· reviewed against the PR's file list and diff,git merge-tree, its check runs and the dev's report6051728326, read 2026-10-08T03:45Z.main. The first line isFixes #11804, andClause-②: nostarts a later line.6051109461's surface. Both sites were measured first, and the files were named before editing.PackagesPage.tsx(+10/−4): the package sheet's Pending changes header<p>becomes a<div>with the same classes.packages/fields/src/widgets/SelectField.tsx(+30/−5): the control value becomes''forundefinedwhen the host passesonChange.@object-ui/app-shelland@object-ui/fieldspatch).packages/components/src/ui/**is untouched.<p>that holds the draft-countBadge(which renders a<div>), notSheetDescription. It fires only when the package has pending drafts. Studio's Package info & settings opens the same sheet.SelectField's single-value branch (field:select, which every select in the object create form gets). It fires on the first pick of an unseeded select, not when defaults load.onChange(a bare SDUI node) stays uncontrolled, so its control does not freeze after a pick. That is pinned (ablation M3).SelectField's props are unchanged; only the value it hands Radix differs, so display and saved values are unchanged.noholds.Local union on
0fefd45(withmaincef0eeemerged in): 302 files and 4780 tests green acrosspackages/fieldsand every test that namesSelectField,select-trigger-orfield:select, plusPackagesPage. Both type-checks and the derivedcheck:*set are green.Ablation, three legs, each in the predicted direction:
<p>: React's nesting errors return.undefinedbranch removed: "Select is changing from uncontrolled to controlled" returns.onChangeguard dropped: the bare host freezes on its placeholder.Each restore was proven by blob hash.
git merge-treeis clean againstmainand against objectui#11868, fix(app-shell): the form designer's drag live region names labels and places, not ids (objectui#11802) #11869 and fix(app-shell,console): zh names a Studio pillar by its tab label; settings label probes stop logging missing-translation warnings (objectui#11801) #11870.0fefd45: converging, none red at this read. The PR is queued when every check completes.BuiltinSelectControl(baretype: 'select',packages/components/src/renderers/form/form.tsx) logs the same warning on a first pick. It was measured in happy-dom, but no public door was measured (the object create form never reaches it). It is in the PR's Acceptance notes.huangyiirene.Generated by Claude Code
objectstack-fleet commentedon Oct 8, 2026
Landed: PR objectui#11879 →
main3035948domain:uiseat 1 ·session_01DrKzdPdyLLBW3qpZ4vtk7z· verified 2026-10-08T04:23Z.0fefd45before queueing: 40 of 43 check runs passed, and the 3 skipped are the expected ones.check-governed-merges.mjs: not governed, +319/−9.3035948is one squash commit on parent99c481d. It changes 5 files, +319/−9, and all 5 are blob-identical to the reviewed head0fefd45. The whole diff's patch-id matches (be8c9592…).completedby the PR'sFixes.pm:dispatchedwas removed in the same pass and read back.<p>holding aBadge. The other isSelectField's first pick on an unseeded select.BuiltinSelectControlhas the same warning shape, with no measured public door. It is noted in PR objectui#11879's Acceptance notes and not filed.Generated by Claude Code
fix(app-shell,fields): valid package-sheet header markup; select fiel…