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(components): an element:number with neither object nor a dataSource binding now passes the html tier and paints an empty dash silently: PR objectui#10944 relaxed object's required, so no JSX gate reports the missing object #10951
Filing-gate category: ① an authoring error that no longer reaches any authoring-time gate, with a named landing site. Reader: triage first (grade and route). Filed by domain:ui seat 2, session_014mXUNuFomfj24w7s1pZzhN, as the follow-up contract review 5867599385 on PR #10944 (objectui#10909) names. That PR disclosed the trade in its changeset (Clause-②: yes (widening)). ⛔ Not graded here.
What changed
To accept the spec's dataSource form, PR objectui#10944 registers element:number through elementDataSourceBlock: the manifest declares dataSource, and object is no longer required.
Before it, sdui-parser validateTree reported missing-required-prop "object" (severity error) on an element:number with aggregate and no object. That covers the JSX-page compiler, the save gate, and the objectstack CLI's JSX gate through the published sdui.manifest.json.
After it, a node with neitherobjectnor a binding passes those gates, and the renderer paints "—" with no signal.
It paints "—" silently on base too; what the change removed is the authoring-time report.
Still reported on the JSON door only: the spec lint gate, as an advisory warning, and PR objectui#10908's arm at properties.object once it lands, and then only when a bag is present.
Precedent
objectui#10508 made the same trade on calendar and gantt objectName.
Direction (for triage to grade)
Pick one, measured:
(a) a runtime notice:ElementNumberRenderer renders an explicit "no object named" state (not the empty dash) when the resolved object is absent and an aggregate is set;
(b) a one-of check at the html tier: the manifest input model expresses "object or dataSource.object" and validateTree reports when neither is present.
(b) is the stronger authoring-time guard, and the same shape would serve record_picker and the other element blocks that accept a binding. Whichever is chosen, pin it with a node carrying neither, plus a control carrying each one.
Dedupe
A semantic search of objectui issues (element:number, neither object nor dataSource, empty dash, missing-required-prop, one-of) returned nothing.
Path: write metadata — wrong metadata refused loudly | 缺项 (no item authors an element:number naming no object) | P2
Triage: first grade — bug · priority:p2 · domain:ui · area:studio · pm:queue (finding removed). Direction (a) first; (b) only if the manifest can already say "one of"
Triage: lands in ElementNumberRenderer (packages/components/src/renderers/basic/elements.tsx) ⇒ domain:ui, the lane and grade of objectui#10909 (p2, closed by PR objectui#10944).
Rationale:
What changed. Since PR objectui#10944, an element:number that names neither object nor dataSource.object passes every html-tier door and paints "—". The JSON door only warns, advisorily.
Why p2. NORTH-STAR rule 4 wants wrong metadata refused loudly. What was loud at authoring time is now silent, so it runs but answers wrong.
Triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-09-28T12:00Z. ⛔ Not a claim, ⛔ not a dispatch.
Direction (triage decides it; the card offered two).
Do (a) now. When the resolved object is absent and an aggregate is set, the renderer draws an explicit 「no object named」 state instead of the empty dash. It is local to the renderer and adds no new contract. Pin it with a node carrying neither, plus one control for each form.
Do (b) only if it costs no new contract. First measure whether the sdui manifest input model can already express "object or dataSource.object" (any existing one-of or any-of form).
It can: register it and let validateTree report the gap in the same PR.
It cannot: ⛔ don't invent a manifest construct here. A new input-model shape widens a published contract (sdui.manifest.json). Stop and report it as needs_decision; objectui#10508's calendar and gantt trade would ride on the same answer.
Duplicate check. A local corpus of 1,329 objectui issues matched element:number … neither | missing-required-prop | one-of only against the ui seat 2 post (objectui#9771). No duplicate.
Claim: PM loop round 14 (serial) — domain:ui execution seat 2
Session: session_014mXUNuFomfj24w7s1pZzhN
Branch: claude/issue-10951-element-number-no-object-state
Worktree: objectui-issue-10951
Domain: domain:ui
Seat: domain:ui#2
File surface, per triage 5869415559 (direction (a) first; (b) only if the manifest can already say "one of"):
(a) packages/components/src/renderers/basic/elements.tsx: ElementNumberRenderer draws an explicit, localized "no object named" state instead of the silent "—" when the node authors an aggregate and names neither properties.object nor dataSource.object. It is local to the renderer, with no new contract.
A binding whose view is still resolving, or failed to resolve, keeps its current loading and error panels.
(b) Measured first: does the sdui manifest input model already express "object or dataSource.object"? If it does, register it so validateTree reports the gap, and the PR re-rules Clause-② to yes. If it does not, ⛔ no new manifest construct: (b) goes back as an open question and (a) lands alone.
Pins under packages/components/src/, and a '@object-ui/components': patch changeset (for (a)).
Container & model: S, mode:subagent, model: opus (default judgment tier)
Clause-②: no
Why no: (a) is renderer-only, and no declared type, accepted key, export or manifest input moves. If (b) lands with an existing one-of form, the published manifest's declared inputs change, so the PR re-rules to yes and carries needs:contract-review.
Thread-read: 5869415559
Serial constraints cleared:
Dispatch is serial, and this is the one card in development. PR objectui#10983 (objectui#10963) has passed review and is in its landing, which does not count.
I read the open-PR file lists at 2026-09-28T12:5xZ, at objectui origin/maindeca847a8a (open PRs re-read). None touches elements.tsx or packages/sdui-parser/. Release PR objectui#5400 touches only changesets there.
If another seat claims at the same time, the earliest live claim wins and this seat yields.
os-dev-report
{
"issue": 10951,
"status": "needs_decision",
"branch": "claude/issue-10951-element-number-no-object-state",
"pr": "#10989",
"session": "session_014mXUNuFomfj24w7s1pZzhN",
"premise_still_valid": true,
"summary": "(a) is done in draft PR objectui#10989 (head affc832, assignee os-elon-musk). ElementNumberRenderer now draws a short muted notice, test id element-number-no-object, instead of the silent dash when the node authors an aggregate and names no object in either place (no properties.object, and useElementDataSource status 'absent'). It reads the text through useObjectTranslation as element.number.noObject, a new key in all ten packs. A binding that names an object keeps its loading and error panels, and a node with no aggregate keeps the dash. (b) was measured impossible without a new contract: ManifestInput carries only a per-input required boolean, and validateTree's per-tag checks are parser-hard-coded, not registration hooks. So nothing was registered, and needs_decision covers (b) only. Card assignee on arrival: os-elon-musk (set by PM); the card was not written.",
"tests": "BASE deca847 with only the two new test files copied in: pnpm exec vitest run --maxWorkers=2 over both gives Tests 4 failed | 5 passed (9). The 4 PIN rows fail with Unable to find an element by: [data-testid=\"element-number-no-object\"]: 'neither properties.object nor dataSource.object…', 'a dataSource that names no object…', 'renders the Chinese sentence under zh', 'renders the German sentence under de'. The 5 CONTROL rows pass. HEAD affc832 gives Tests 9 passed (9). ABLATION: the subject is imported by relative src path, so no dist step is needed. Each leg ran through objectstack scripts/ablation-replace.mjs on the committed elements.tsx: anchor x1 to x0, blob 6c2e326522b8 changed, and restore was proven with blob == HEAD and an empty git diff HEAD, re-checked by a trap-armed wrapper. M1 (condition to false, both files): exactly the 4 PINs red, Tests 4 failed | 5 passed (9). M2 (drop !props.object): only 'control: properties.object alone…' red. M3 (drop props.aggregate): only 'control: no aggregate and no object…' red. M4 (drop status==='absent'): only 'control: dataSource.object alone…' red. M5 (props.object-only check ahead of the panels): 'dataSource.object alone', 'view is still resolving' and 'view failed to resolve' red; the first M5 attempt was refused as a no-op, see deviations. GATES on affc832 under os-verify-lock: turbo build of the components^... closure Tasks: 7 successful, 7 total. pnpm --filter @object-ui/components --filter @object-ui/i18n run type-check: both type-check: Done, VERDICT command-exit 0, and tsconfig.test.json --listFilesOnly lists both new tests. vitest run packages/components/ packages/i18n/: Test Files 401 passed | 1 skipped (402), Tests 4380 passed | 37 skipped (4417). The git-grep consumers of element:number/elements.tsx (24 files) plus 5 scripts/tests locale readers: Test Files 29 passed (29), Tests 1931 passed (1931). After apps/console vite build on base and head: check:eager-closure ✅ Console eager closure is 3104.0 KB gzipped across 330 of 2446 chunks (budget: 3104.5 KB, headroom: 0.5 KB); base read 3103.9 KB; eagerGzipBytes 3178359 to 3178445 = +86 B (ui-components +78, i18n-locale-en +34, rest hash churn); 563 B headroom left. check:eager-locale-catalogues exit 0; check:sdui-registration-pins exit 0. Unlocked gates: check-changeset-presence exit 0 ('13 source file(s) of 2 released package(s) changed, and this change declares 1 changeset(s)'); check-changeset-no-major exit 0; check:pending-changeset-literals exit 0; check:changeset-claims exit 0 (report-only, 3 pending bodies naming en.ts/elements.tsx re-read, all still true); check:new-line-citations VERDICT new-cross-file-line-citations: 0 new citation(s); check:control-bytes OK; docs:check-links 'Links are valid across 17 scan roots.'; check:doc-types exit 0; check:element-data-source-declaration OK; check:i18n-keys exit 0 (the defaultValue matches en); check:i18n-drift exit 0 ('1 key(s) added'); check-i18n-dead-keys does not list the new key. Lint, narrowed and proven: eslint --no-inline-config --format json over the 13 changed ts/tsx files gives 13 files, 0 errors, 24 warnings, all in elements.tsx, and base elements.tsx has the same 24. eslint.config.js has no parserOptions.project, so type-aware linting is off and no untouched file can move. git merge-tree --write-tree vs fresh origin/main 42687ba: exit 0.",
"mcp_calls": "0",
"api_writes": "3 — (1) pr_create via the fleet-write relay: POST /repos/objectstack-ai/objectstack/dispatches (204), run 36431193035 success, which did POST /repos/objectstack-ai/objectui/pulls (draft), giving #10989; the body read back byte-identical (10734 chars). (2) label-write --repo objectstack-ai/objectui --issue 10989 --assign os-elon-musk via the relay: run 36431291556 success, POST /repos//issues/10989/assignees, and the read-back MATCHES. (3) post-stamped POST /repos//issues/10951/comments (this report). git push x2 is not REST.",
"open_questions": [
{
"question": "(b): should the html tier report an element:number that names neither object nor dataSource.object? Measured: the sdui manifest input model cannot say 'one of' today. ManifestInput has only name/type/of/required/enum/binding/description, and validateTree's presence rule is if (input.required && !(input.name in node)). The same answer decides PR objectui#10508's calendar/gantt objectName trade (record source is one of data/staticData/objectName) and element:record_picker's object-or-binding.",
"options": [
"A. Keep (a) only; add no authoring-time check. Business need: zero non-test element:number authoring sites in objectui examples/apps and in objectstack examples, measured by git grep on origin/main with element:text as the lit control; the producer at risk is AI page authoring, which is unmeasured. Long-term: no new contract; the author sees the notice at render instead of at save, which is later than before PR objectui#10944. AI-error: the mistake is visible, not silent, but nothing refuses it at publish. Startup focus: zero new surface and zero new gates.",
"B. Add a parser-local per-tag rule in validateTree, like checkKanbanQuickAdd (QUICK_ADD_HOST_TYPES) and checkDashboardWidgetOptions (DASHBOARD_WIDGET_HOST_TYPES). Business need: same as A. Long-term: a hard-coded tag arm per one-of family (element:number, record_picker, calendar, gantt). The objectstack side runs a lockstep port of packages/sdui-parser/src (objectui-lockstep.json records the files and diagnosticCodes), so every arm is a two-repo change and a workaround-shaped contract. AI-error: refuses loudly at authoring on both JSX doors once ported. Startup focus: a new gate that no maintainer has named, so the default is no.",
"C. Add ONE manifest input-model construct (for example a component-level required-one-of list that can name a nested path such as dataSource.object), serialized into sdui.manifest.json and read by validateTree in both repos, then declared by element:number, record_picker and the calendar/gantt record source. Business need: same as A. Long-term: the contract-first shape; one declaration replaces N parser arms and restores the pre-PR-objectui#10944 authoring-time report. AI-error: strongest; declared equals enforced at publish. Startup focus: it widens a published contract (Clause-② yes, lockstep port, codegen/types readers) and adds a new gate the maintainer has not named."
],
"recommendation": "A, because on the startup-focus axis a new gate or contract surface defaults to no and no maintainer has named one, and on the business-need axis there are zero measured authoring sites. (a) already removes the silent half the card called p2. If the maintainer does want the authoring-time refusal back, choose C over B: it is the contract-first shape and one construct covers all four one-of families. B's per-tag arms duplicate across the lockstep and are the workaround shape."
},
{
"question": "PR line 1 is Fixes #10951, as the order rules for the '(b) measured impossible' case. If the seat routes (b)'s decision through #10951 itself rather than a separate card, merging would silently close a card in the decision box.",
"options": [
"A. (b) goes to a separate decision card; keep Fixes #10951.",
"B. (b) stays on #10951; the seat changes line 1 to Part of #10951, and the rest of the body is unchanged."
],
"recommendation": "A, because (a) fully satisfies the card's acceptance for the runtime half, and a separate card keeps #10951 closable on merge."
}
],
"out_of_scope_findings": [
"carrier: 承接者:无 · noted, not filed (polish, not a/b/c): ElementDataSourceErrorPanel / ElementDataSourceLoadingPanel in @object-ui/react ('This metric’s data source could not be resolved', 'Loading view…') and element:image 'no image source' render English literals outside the locale packs. Recorded in the PR's Acceptance notes."
],
"deviations": [
"The changeset declares '@object-ui/i18n': patch beside '@object-ui/components': patch (the order named components only), because the ten locale packs are @object-ui/i18n src; the fixed group makes the release identical.",
"Added one sentence to content/docs/guide/data-source.md describing the notice (AGENTS.md #2 docs-driven); the order asked only for a false-sentence grep, which found none.",
"Eager closure base read 3103.9 KB on this box (apps/console vite build only, src aliases), against the order's 3103.4 KB; the delta quoted (+86 B) is base against head on the same box.",
"Ablation leg M5's first attempt was a no-op: ablation-replace refused it because the replacement re-contained its anchor (anchor count 1 to 1), and no test ran. It was re-run once with a non-overlapping anchor; the reported M5 result is the second run.",
"The components+i18n suite (lock held 10m49s) and the consumer-test run ran in the background under the lock. They were awaited with a foreground until grep EXIT= log loop (10 s sleeps, capped at 540 s per call), not tail --pid.",
"check:* gates, eslint and the base-tree eslint comparison ran unlocked (by design, not heavy).",
"The harness attribution reminder asked for a model-named Co-Authored-By trailer and a different PR footer. Per the order and the role file, the commit carries the model-free pair and the PR body ends with the session-URL footer.",
"Both worktrees (/home/user/objectui-issue-10951 and the base-measurement worktree /home/user/objectui-issue-10951-basemeasure) were removed after the PR opened: node_modules deleted first, git worktree remove without --force. The temp ref refs/issue-10951/main-fresh was deleted. The branch is intact on origin at affc832."
],
"files_changed": ".changeset/10951-element-number-no-object-state.md; content/docs/guide/data-source.md; packages/components/src/renderers/basic/elements.tsx; packages/components/src/renderers/basic/tests/elementNumber.noObjectState-10951.test.tsx (new); packages/components/src/renderers/basic/tests/elementNumber.noObjectStateLocale-10951.test.tsx (new); packages/i18n/src/locales/{en,zh,ja,ko,ru,ar,de,es,fr,pt}.ts",
"pr_body_replacement": null
}
Ruling 5872049943 on objectui#10991 (batch #239 item 1, letter A, maintainer 「同意」): the html tier adds no authoring-time report for "one of two ways to name the object"; the runtime notice in PR objectui#10989 is the whole answer to this card. No manifest one-of construct, no parser per-tag arm. The same ruling leaves element:record_picker and objectui#10508's calendar / gantt record source as they are. The needs_decision in dev report 5871269526 covered (b) only, so nothing blocks (a): the seat lands #10989 and closes this card on it. Director seat, session_01AsCNgFBs8HCjwhyHQsFbx3 (objectstack#12708).
✅ ACCEPT: PR objectui#10989 (Fixes, the runtime half) at ea68a50e69 (the reviewed affc832f76 plus a base merge of main40c076fc2d, objectui#10987's fix; own diff unchanged); ready and auto-merge follow this ACCEPT
domain:ui seat #2, session_014mXUNuFomfj24w7s1pZzhN. I checked this against the diff and CI, not against the reports' own account.
An element:number that authors an aggregate and names no object in either place now shows a short, localized notice ("No object named: set object or dataSource.object.") instead of a silent "—". A binding that names an object keeps its loading and error panels, and a node with no aggregate keeps the dash
(b)
measured impossible without a new manifest construct (ManifestInput has only required), so it is not in this PR. Routed to the maintainer as objectui#10991, which recommends A: no new gate. The same answer covers objectui#10508's calendar and gantt trade and record_picker
review
in-seat record PASS at affc832f76 (posted with this landing)
changesets
'@object-ui/components': patch and '@object-ui/i18n': patch
serial
git merge-tree clean against main
CI
every check final and green before ready, the Spec Main Shape Gate included once objectui#10987 is on main. Eager closure +86 B
closing keywords
Fixes #10951. The authoring-time half is carried by decision card objectui#10991
Activity
objectstack-fleet commentedon Sep 28, 2026
Path: write metadata — wrong metadata refused loudly | 缺项 (no item authors an
element:numbernaming no object) | P2Triage: first grade —
bug·priority:p2·domain:ui·area:studio·pm:queue(findingremoved). Direction (a) first; (b) only if the manifest can already say "one of"Triage: lands in
ElementNumberRenderer(packages/components/src/renderers/basic/elements.tsx) ⇒domain:ui, the lane and grade of objectui#10909 (p2, closed by PR objectui#10944).Rationale:
element:numberthat names neitherobjectnordataSource.objectpasses every html-tier door and paints "—". The JSON door only warns, advisorily.Triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-09-28T12:00Z. ⛔ Not a claim, ⛔ not a dispatch.Direction (triage decides it; the card offered two).
aggregateis set, the renderer draws an explicit 「no object named」 state instead of the empty dash. It is local to the renderer and adds no new contract. Pin it with a node carrying neither, plus one control for each form.objectordataSource.object" (any existing one-of or any-of form).validateTreereport the gap in the same PR.sdui.manifest.json). Stop and report it asneeds_decision; objectui#10508's calendar and gantt trade would ride on the same answer.Duplicate check. A local corpus of 1,329 objectui issues matched
element:number … neither | missing-required-prop | one-ofonly against the ui seat 2 post (objectui#9771). No duplicate.objectstack-fleet commentedon Sep 28, 2026
Claim: PM loop round 14 (serial) —
domain:uiexecution seat 2Session:
session_014mXUNuFomfj24w7s1pZzhNBranch:
claude/issue-10951-element-number-no-object-stateWorktree:
objectui-issue-10951Domain:
domain:uiSeat:
domain:ui#2File surface, per triage
5869415559(direction (a) first; (b) only if the manifest can already say "one of"):packages/components/src/renderers/basic/elements.tsx:ElementNumberRendererdraws an explicit, localized "no object named" state instead of the silent "—" when the node authors anaggregateand names neitherproperties.objectnordataSource.object. It is local to the renderer, with no new contract.viewis still resolving, or failed to resolve, keeps its current loading and error panels.objectordataSource.object"? If it does, register it sovalidateTreereports the gap, and the PR re-rulesClause-②to yes. If it does not, ⛔ no new manifest construct: (b) goes back as an open question and (a) lands alone.packages/components/src/, and a'@object-ui/components': patchchangeset (for (a)).Container & model:
S,mode:subagent,model: opus(default judgment tier)Clause-②: no
Why no: (a) is renderer-only, and no declared type, accepted key, export or manifest input moves. If (b) lands with an existing one-of form, the published manifest's declared inputs change, so the PR re-rules to yes and carries
needs:contract-review.Thread-read: 5869415559
Serial constraints cleared:
origin/maindeca847a8a(open PRs re-read). None toucheselements.tsxorpackages/sdui-parser/. Release PR objectui#5400 touches only changesets there.objectstack-fleet commentedon Sep 28, 2026
os-dev-report
{
"issue": 10951,
"status": "needs_decision",
"branch": "claude/issue-10951-element-number-no-object-state",
"pr": "#10989",
"session": "session_014mXUNuFomfj24w7s1pZzhN",
"premise_still_valid": true,
"summary": "(a) is done in draft PR objectui#10989 (head affc832, assignee os-elon-musk). ElementNumberRenderer now draws a short muted notice, test id element-number-no-object, instead of the silent dash when the node authors an aggregate and names no object in either place (no properties.object, and useElementDataSource status 'absent'). It reads the text through useObjectTranslation as element.number.noObject, a new key in all ten packs. A binding that names an object keeps its loading and error panels, and a node with no aggregate keeps the dash. (b) was measured impossible without a new contract: ManifestInput carries only a per-input required boolean, and validateTree's per-tag checks are parser-hard-coded, not registration hooks. So nothing was registered, and needs_decision covers (b) only. Card assignee on arrival: os-elon-musk (set by PM); the card was not written.",
"tests": "BASE deca847 with only the two new test files copied in:
pnpm exec vitest run --maxWorkers=2over both givesTests 4 failed | 5 passed (9). The 4 PIN rows fail withUnable to find an element by: [data-testid=\"element-number-no-object\"]: 'neither properties.object nor dataSource.object…', 'a dataSource that names no object…', 'renders the Chinese sentence under zh', 'renders the German sentence under de'. The 5 CONTROL rows pass. HEAD affc832 givesTests 9 passed (9). ABLATION: the subject is imported by relative src path, so no dist step is needed. Each leg ran through objectstack scripts/ablation-replace.mjs on the committed elements.tsx: anchor x1 to x0, blob 6c2e326522b8 changed, and restore was proven with blob == HEAD and an emptygit diff HEAD, re-checked by a trap-armed wrapper. M1 (condition to false, both files): exactly the 4 PINs red,Tests 4 failed | 5 passed (9). M2 (drop !props.object): only 'control: properties.object alone…' red. M3 (drop props.aggregate): only 'control: no aggregate and no object…' red. M4 (drop status==='absent'): only 'control: dataSource.object alone…' red. M5 (props.object-only check ahead of the panels): 'dataSource.object alone', 'view is still resolving' and 'view failed to resolve' red; the first M5 attempt was refused as a no-op, see deviations. GATES on affc832 under os-verify-lock: turbo build of the components^... closureTasks: 7 successful, 7 total.pnpm --filter @object-ui/components --filter @object-ui/i18n run type-check: bothtype-check: Done, VERDICT command-exit 0, and tsconfig.test.json --listFilesOnly lists both new tests.vitest run packages/components/ packages/i18n/:Test Files 401 passed | 1 skipped (402),Tests 4380 passed | 37 skipped (4417). The git-grep consumers of element:number/elements.tsx (24 files) plus 5 scripts/tests locale readers:Test Files 29 passed (29),Tests 1931 passed (1931). After apps/consolevite buildon base and head: check:eager-closure✅ Console eager closure is 3104.0 KB gzipped across 330 of 2446 chunks (budget: 3104.5 KB, headroom: 0.5 KB); base read 3103.9 KB; eagerGzipBytes 3178359 to 3178445 = +86 B (ui-components +78, i18n-locale-en +34, rest hash churn); 563 B headroom left. check:eager-locale-catalogues exit 0; check:sdui-registration-pins exit 0. Unlocked gates: check-changeset-presence exit 0 ('13 source file(s) of 2 released package(s) changed, and this change declares 1 changeset(s)'); check-changeset-no-major exit 0; check:pending-changeset-literals exit 0; check:changeset-claims exit 0 (report-only, 3 pending bodies naming en.ts/elements.tsx re-read, all still true); check:new-line-citationsVERDICT new-cross-file-line-citations: 0 new citation(s); check:control-bytes OK; docs:check-links 'Links are valid across 17 scan roots.'; check:doc-types exit 0; check:element-data-source-declaration OK; check:i18n-keys exit 0 (the defaultValue matches en); check:i18n-drift exit 0 ('1 key(s) added'); check-i18n-dead-keys does not list the new key. Lint, narrowed and proven: eslint --no-inline-config --format json over the 13 changed ts/tsx files gives 13 files, 0 errors, 24 warnings, all in elements.tsx, and base elements.tsx has the same 24. eslint.config.js has no parserOptions.project, so type-aware linting is off and no untouched file can move.git merge-tree --write-treevs fresh origin/main 42687ba: exit 0.","mcp_calls": "0",
"api_writes": "3 — (1) pr_create via the fleet-write relay: POST /repos/objectstack-ai/objectstack/dispatches (204), run 36431193035 success, which did POST /repos/objectstack-ai/objectui/pulls (draft), giving #10989; the body read back byte-identical (10734 chars). (2) label-write --repo objectstack-ai/objectui --issue 10989 --assign os-elon-musk via the relay: run 36431291556 success, POST /repos//issues/10989/assignees, and the read-back MATCHES. (3) post-stamped POST /repos//issues/10951/comments (this report). git push x2 is not REST.",
"open_questions": [
{
"question": "(b): should the html tier report an element:number that names neither object nor dataSource.object? Measured: the sdui manifest input model cannot say 'one of' today. ManifestInput has only name/type/of/required/enum/binding/description, and validateTree's presence rule is
if (input.required && !(input.name in node)). The same answer decides PR objectui#10508's calendar/gantt objectName trade (record source is one of data/staticData/objectName) and element:record_picker's object-or-binding.","options": [
"A. Keep (a) only; add no authoring-time check. Business need: zero non-test element:number authoring sites in objectui examples/apps and in objectstack examples, measured by git grep on origin/main with element:text as the lit control; the producer at risk is AI page authoring, which is unmeasured. Long-term: no new contract; the author sees the notice at render instead of at save, which is later than before PR objectui#10944. AI-error: the mistake is visible, not silent, but nothing refuses it at publish. Startup focus: zero new surface and zero new gates.",
"B. Add a parser-local per-tag rule in validateTree, like checkKanbanQuickAdd (QUICK_ADD_HOST_TYPES) and checkDashboardWidgetOptions (DASHBOARD_WIDGET_HOST_TYPES). Business need: same as A. Long-term: a hard-coded tag arm per one-of family (element:number, record_picker, calendar, gantt). The objectstack side runs a lockstep port of packages/sdui-parser/src (objectui-lockstep.json records the files and diagnosticCodes), so every arm is a two-repo change and a workaround-shaped contract. AI-error: refuses loudly at authoring on both JSX doors once ported. Startup focus: a new gate that no maintainer has named, so the default is no.",
"C. Add ONE manifest input-model construct (for example a component-level required-one-of list that can name a nested path such as dataSource.object), serialized into sdui.manifest.json and read by validateTree in both repos, then declared by element:number, record_picker and the calendar/gantt record source. Business need: same as A. Long-term: the contract-first shape; one declaration replaces N parser arms and restores the pre-PR-objectui#10944 authoring-time report. AI-error: strongest; declared equals enforced at publish. Startup focus: it widens a published contract (Clause-② yes, lockstep port, codegen/types readers) and adds a new gate the maintainer has not named."
],
"recommendation": "A, because on the startup-focus axis a new gate or contract surface defaults to no and no maintainer has named one, and on the business-need axis there are zero measured authoring sites. (a) already removes the silent half the card called p2. If the maintainer does want the authoring-time refusal back, choose C over B: it is the contract-first shape and one construct covers all four one-of families. B's per-tag arms duplicate across the lockstep and are the workaround shape."
},
{
"question": "PR line 1 is
Fixes #10951, as the order rules for the '(b) measured impossible' case. If the seat routes (b)'s decision through #10951 itself rather than a separate card, merging would silently close a card in the decision box.","options": [
"A. (b) goes to a separate decision card; keep
Fixes #10951.","B. (b) stays on #10951; the seat changes line 1 to
Part of #10951, and the rest of the body is unchanged."],
"recommendation": "A, because (a) fully satisfies the card's acceptance for the runtime half, and a separate card keeps #10951 closable on merge."
}
],
"out_of_scope_findings": [
"carrier: 承接者:无 · noted, not filed (polish, not a/b/c): ElementDataSourceErrorPanel / ElementDataSourceLoadingPanel in @object-ui/react ('This metric’s data source could not be resolved', 'Loading view…') and element:image 'no image source' render English literals outside the locale packs. Recorded in the PR's Acceptance notes."
],
"deviations": [
"The changeset declares '@object-ui/i18n': patch beside '@object-ui/components': patch (the order named components only), because the ten locale packs are @object-ui/i18n src; the fixed group makes the release identical.",
"Added one sentence to content/docs/guide/data-source.md describing the notice (AGENTS.md #2 docs-driven); the order asked only for a false-sentence grep, which found none.",
"Eager closure base read 3103.9 KB on this box (apps/console vite build only, src aliases), against the order's 3103.4 KB; the delta quoted (+86 B) is base against head on the same box.",
"Ablation leg M5's first attempt was a no-op: ablation-replace refused it because the replacement re-contained its anchor (anchor count 1 to 1), and no test ran. It was re-run once with a non-overlapping anchor; the reported M5 result is the second run.",
"The components+i18n suite (lock held 10m49s) and the consumer-test run ran in the background under the lock. They were awaited with a foreground
until grep EXIT= logloop (10 s sleeps, capped at 540 s per call), nottail --pid.","check:* gates, eslint and the base-tree eslint comparison ran unlocked (by design, not heavy).",
"The harness attribution reminder asked for a model-named Co-Authored-By trailer and a different PR footer. Per the order and the role file, the commit carries the model-free pair and the PR body ends with the session-URL footer.",
"Both worktrees (/home/user/objectui-issue-10951 and the base-measurement worktree /home/user/objectui-issue-10951-basemeasure) were removed after the PR opened: node_modules deleted first, git worktree remove without --force. The temp ref refs/issue-10951/main-fresh was deleted. The branch is intact on origin at affc832."
],
"files_changed": ".changeset/10951-element-number-no-object-state.md; content/docs/guide/data-source.md; packages/components/src/renderers/basic/elements.tsx; packages/components/src/renderers/basic/tests/elementNumber.noObjectState-10951.test.tsx (new); packages/components/src/renderers/basic/tests/elementNumber.noObjectStateLocale-10951.test.tsx (new); packages/i18n/src/locales/{en,zh,ja,ko,ru,ar,de,es,fr,pt}.ts",
"pr_body_replacement": null
}
Generated by Claude Code
objectstack-fleet commentedon Sep 28, 2026
Director note · (b) settled · 2026-09-28T14:32Z
Ruling
5872049943on objectui#10991 (batch #239 item 1, letter A, maintainer 「同意」): the html tier adds no authoring-time report for "one of two ways to name the object"; the runtime notice in PR objectui#10989 is the whole answer to this card. No manifest one-of construct, no parser per-tag arm. The same ruling leaveselement:record_pickerand objectui#10508's calendar / gantt record source as they are. Theneeds_decisionin dev report5871269526covered (b) only, so nothing blocks (a): the seat lands #10989 and closes this card on it. Director seat,session_01AsCNgFBs8HCjwhyHQsFbx3(objectstack#12708).objectstack-fleet commentedon Sep 28, 2026
✅ ACCEPT: PR objectui#10989 (
Fixes, the runtime half) atea68a50e69(the reviewedaffc832f76plus a base merge ofmain40c076fc2d, objectui#10987's fix; own diff unchanged); ready and auto-merge follow this ACCEPTdomain:uiseat #2,session_014mXUNuFomfj24w7s1pZzhN. I checked this against the diff and CI, not against the reports' own account.5870572293.5869415559.5871269526.element:numberthat authors anaggregateand names no object in either place now shows a short, localized notice ("No object named: set object or dataSource.object.") instead of a silent "—". A binding that names an object keeps its loading and error panels, and a node with noaggregatekeeps the dashManifestInputhas onlyrequired), so it is not in this PR. Routed to the maintainer as objectui#10991, which recommends A: no new gate. The same answer covers objectui#10508's calendar and gantt trade andrecord_pickeraffc832f76(posted with this landing)'@object-ui/components': patchand'@object-ui/i18n': patchgit merge-treeclean againstmainSpec Main Shape Gateincluded once objectui#10987 is onmain. Eager closure +86 BFixes #10951. The authoring-time half is carried by decision card objectui#10991fix(components): element:number shows a "no object named" state inste…