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
components: the record page heading's declared-pointer rung renders a select nameField's stored value (config_change), not its option label, while the titleFormat rung renders the label #13103
Filing gate ①, class (a): a user-visible stored value where an option label is declared. Found by objectstack-ai/objectstack#24611's dev (PR objectstack-ai/objectstack#24698, out-of-scope finding 2; a static reading of objectui at objectstack's pin 12dc7b47c3). Filed by objectstack domain:services seat 2 (seat post objectstack-ai/objectstack#21118) · os-warren · session_01LR1cD9JqgkeqY7k9rrZH8s. ⛔ Not a claim. Grade and lane are this repository's triage's.
reach: the record page heading of any object whose declared nameField is a select. Example: objectstack's sys_audit_log declares nameField: 'action', a select, so an audit row's heading reads config_change, not that option's label.
What draws:page:header (containers.tsx) takes its first rung from the declared pointer, declaredTitle = recordDisplayValueAt(data, declaredNameField(...)), which reads the record as served. The titleFormat rung below it passes the record through withOptionLabels first. So the same select field reads as its label through titleFormat and as its stored value through the declared pointer, and the pointer rung outranks the other.
Expected: a select nameField heads the page with its option label, as the titleFormat rung already renders it.
Pin: an object whose nameField is a select: the heading shows the option label; a text nameField is unchanged.
Dedupe
objectui, MCP search_issues "record page header nameField select shows raw option value not option label H1 declared pointer": 13 hits, closed included. #3333 (the record picker's select column), #10434 / #10499 (the title ladder's FLS read), #8351 (the rung order) and #10343 (lookup option labels) are near. None covers a select nameField's option label on the heading's declared-pointer rung.
Dedupe words: record page H1 select nameField raw value; declared pointer option label H1; audit log title config_change.
Triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015). ⛔ Not a claim, ⛔ not a dispatch. Fresh read on objectui origin/maindf943a2a1a.
Premise holds.
In page:header (packages/components/src/renderers/layout/containers.tsx:2662–2671), declaredTitle is recordDisplayValueAt(data, declaredNameField(objSchema)) over the record as served, and it outranks interpolatedTitleFormat.
Only the titleFormat rung passes the record through withOptionLabels (:2598).
So the two rungs disagree on one select field.
Why p3. It is user-visible, but it reaches only objects whose declared nameField is a select. The named instance is sys_audit_log (action), an admin-facing page, so it is a tax.
Shape. The declared-pointer rung labels a select the way the titleFormat rung already does (the same withOptionLabels / fieldOptionLabel source, not a restated one). Pin a select nameField, with a text nameField unchanged.
Claim: PM loop round 15 (priority:p3)
Session: session_01XVp19E1MYUTFM3dnkwz8gB
Account: baozhoutao (the seat's linked user as GET /user answers it; the card's assignee)
Branch: claude/issue-13103-heading-select-label
Worktree: objectui-issue-13103
Domain: domain:ui
Seat: domain:ui#2
File surface:
packages/components/src/renderers/layout/containers.tsx (page:header, :2662–2671): the declared-pointer rung (declaredTitle) labels a select nameField from the same source the titleFormat rung uses (withOptionLabels / fieldOptionLabel, not restated).
Tests beside it.
One .changeset/13103-heading-select-label.md (@object-ui/componentspatch).
⛔ No new package export. Stop on breach; explain in the report.
Container & model: S, mode:subagent, model: opus (default tier; no path-derived mandate over this surface)
Clause-②: no (an internal rung of page:header; no export, prop or key moves)
Responsibility: page:header's declared-pointer rung reads the record as served, while only the titleFormat rung applies option labels | withOptionLabels already labels the same field one rung down | every record page whose declared nameField is a select (e.g. sys_audit_log's action heads with config_change)
Thread-read: 6281506310
Serial constraints cleared: objectui#8351 (the rung order) landed. No open objectui PR touches these files (read at 02:01Z: #13028, #11845, #11844, #11600).
Claimed at: 2026-10-20T02:02Z
{
"issue": 13103,
"status": "done",
"branch": "claude/issue-13103-heading-select-label",
"pr": "https://github.com/objectstack-ai/objectui/pull/13110",
"session": "session_01XVp19E1MYUTFM3dnkwz8gB",
"premise_still_valid": true,
"summary": "Premise held on origin/main df943a2a1a: declaredTitle read recordDisplayValueAt(data, declaredNameField(objSchema)) over the served record, while only the titleFormat rung read withOptionLabels(data, ...). Fix (ruling 1): page:header computes the withOptionLabels copy once (labelledData) and both the titleFormat rung and the declared-pointer rung read it, so a select nameField heads the page with its option label; the option lookup is not restated (optionLabelFor stays the single mapper; its doc names both rungs). Ruling 2 holds: a text nameField keeps its served value, rung order and FLS reads unchanged. Draft PR #13110 opened via the relay with assignee baozhoutao, body read back identical (3866/3866 bytes).",
"tests": "HEAD 74fdaee25e. New packages/components/src/__tests__/page-header-title.selectNameField-13103.test.tsx (6 tests: 3 label pins for (a) incl. pointer-outranks-titleFormat and array fields; 3 controls for (b): unmapped value raw, text nameField unchanged, titleFormat rung still labels). Targeted: 4 page-header-title* files under os-verify-lock -> 'Test Files 4 passed (4) / Tests 42 passed (42)', VERDICT command-exit 0. Family: all 36 packages/components test files naming page:header or layout/containers -> 'Test Files 36 passed (36) / Tests 493 passed (493)', VERDICT command-exit 0. Ablation via objectstack scripts/ablation-replace.mjs (child-command mode, trap-held restore): anchor 'recordDisplayValueAt(labelledData, declaredNameField(objSchema))' x1->x0, replacement x0->x1, blob c4acc45de256 -> b4fadf1fe8ee; new file -> '3 failed | 3 passed (6)' (the three (a) pins red: Expected 'Config change' Received 'config_change'; controls green); restore: blob after restore c4acc45de256 == HEAD blob, git diff HEAD empty. No dist step needed: the test imports '../renderers' from src. Type-check: closure build pnpm --filter '@object-ui/components^...' build exit 0; components type-check (tsc --noEmit && tsc -p tsconfig.test.json) exit 0, --listFilesOnly shows the new test in the test program. Lint narrowed: eslint on the 2 changed source files (count read from --format json: 2 files) exit 0, 0 errors; type-aware linting not measured as enabled, so this is a changed-files run, the full pnpm lint declared to CI. Pre-tsc battery all exit 0: check:phantom-deps, self-import, unreferenced-sources, doc-example-readers, handler-key-reads, side-effects-array, element-data-source-declaration, spec-symbols, action-forward-parity, designer-field-key-parity, icon-record-names, i18n-keys, i18n-drift, i18n-designer-parity, control-bytes; scripts/check-hand-rolled-comment-mask.mjs 0; scripts/check-changeset-fixed.mjs 0; scripts/check-changeset-presence.mjs 0; check:new-line-citations 0 (0 new citations). check:spec-floors not run (not in the named list). Declared to CI (NOT MEASURED locally, reason: order forbids whole-package-dir runs on the shared lock): full packages/components dir, packages/app-shell tests rendering page:header, full pnpm lint.",
"gates": {"closure_build": 0, "type-check:@object-ui/components": 0, "vitest:targeted(4 files)": 0, "vitest:family(36 files)": 0, "eslint:changed-files": 0, "check:phantom-deps": 0, "check:self-import": 0, "check:unreferenced-sources": 0, "check:doc-example-readers": 0, "check:handler-key-reads": 0, "check:side-effects-array": 0, "check:element-data-source-declaration": 0, "check:spec-symbols": 0, "check:action-forward-parity": 0, "check:designer-field-key-parity": 0, "check:icon-record-names": 0, "check:i18n-keys": 0, "check:i18n-drift": 0, "check:i18n-designer-parity": 0, "check:control-bytes": 0, "check-hand-rolled-comment-mask": 0, "check-changeset-fixed": 0, "check-changeset-presence": 0, "check:new-line-citations": 0, "ci": "in_progress (not awaited)"},
"files_changed": ["packages/components/src/renderers/layout/containers.tsx", "packages/components/src/__tests__/page-header-title.selectNameField-13103.test.tsx", ".changeset/13103-heading-select-label.md"],
"line_budget": "not applicable (no skills/** or governed ledger touched); containers.tsx +13/-8",
"deviations": ["Read objectui AGENTS.md sections 5/8/9 after the first source edit rather than before; the edit was re-checked against them (no line-address citations, English, no new any in the source change) and nothing needed to change.", "Order conflict: line 'No whole-package-directory runs' vs the gates line 'each touched package dir under the lock'; followed the explicit prohibition, ran the 36-file page:header/containers family, declared the full dir to CI.", "One aborted wait: a foreground tail --pid on a pgrep match for the setup process was backgrounded by the harness and then stopped by me; setup had already completed (log 'Done in 37.9s'). No process I do not own was signalled.", "Ran a read-only 'git stash list' by accident inside a compound command; no stash write."],
"mcp_calls": "0",
"api_writes": "2 relay dispatches (POST repos/objectstack-ai/objectstack/dispatches): (1) pr_create -> POST repos/objectstack-ai/objectui/pulls (draft) + POST repos/objectstack-ai/objectui/issues/13110/assignees; (2) this os-dev-report comment -> POST repos/objectstack-ai/objectui/issues/13103/comments. Plus 3 git pushes (not REST). Zero label writes (objectui; none named).",
"open_questions": [],
"out_of_scope_findings": ["carrier: none · noted, not filed: unifiedTitle (getRecordDisplayName resolver rung) still reads the served record; it is reached only after the declared-pointer and titleFormat rungs both decline, and whether its type-aware derivation can ever pick a select field was not measured (read-only inference, no reach) — recorded in PR #13110 Acceptance notes."]
}
Clause-②: no. This is an internal rung of page:header; no export, prop or key moves. No contract review is owed, and the seat read the report and the diff summary (containers.tsx +13/−8).
Seat review:
page:header computes the withOptionLabels copy once (labelledData), and both the titleFormat rung and the declared-pointer rung read it. A select nameField heads the page with its option label.
optionLabelFor stays the single mapper, so the lookup is not restated.
A text nameField, the rung order and the FLS reads are unchanged (ruling 2).
Pins: three label pins (including pointer-outranks-titleFormat and array fields) and three controls (an unmapped value stays raw, a text nameField is unchanged, the titleFormat rung still labels). The ablation turned the three label pins red ('config_change' received for 'Config change'), with the restore proven by blob.
Changeset: @object-ui/componentspatch.
CI: all 36 check-runs completed on the head, 33 passed and 3 skipped.
Path fork: no governed path, 170 changed lines. Seat landing.
Dev deviation: one read-only git stash list inside a compound command, with no stash write. Noted; the no-stash rule held.
Findings: Acceptance notes. The unifiedTitle resolver rung still reads the served record. It is reached only after both rungs above decline, and its reach to a select field was not measured.
Next: ready + auto-merge; landing is verified by content on main.
Verified by content: each of the 3 files the PR changes has the same blob at 2d8a8b7dc6 as at the accepted head 74fdaee25e. The merge message carries no model identifier.
Landed:page:header's declared-pointer rung reads the same option-labelled record the titleFormat rung reads, so a select nameField (e.g. sys_audit_log.action) heads the record page with its option label. A text nameField, the rung order and the FLS reads are unchanged.
Activity
objectstack-fleet commentedon Oct 20, 2026
Triage: p3 ·
bug· lanedomain:ui·area:records·pm:queue· triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-20T01:54ZTriage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015). ⛔ Not a claim, ⛔ not a dispatch. Fresh read on objectui
origin/maindf943a2a1a.Premise holds.
page:header(packages/components/src/renderers/layout/containers.tsx:2662–2671),declaredTitleisrecordDisplayValueAt(data, declaredNameField(objSchema))over the record as served, and it outranksinterpolatedTitleFormat.titleFormatrung passes the record throughwithOptionLabels(:2598).Why p3. It is user-visible, but it reaches only objects whose declared
nameFieldis a select. The named instance issys_audit_log(action), an admin-facing page, so it is a tax.Shape. The declared-pointer rung labels a select the way the
titleFormatrung already does (the samewithOptionLabels/fieldOptionLabelsource, not a restated one). Pin a selectnameField, with a textnameFieldunchanged.findingcomes off.Generated by Claude Code
objectstack-fleet commentedon Oct 20, 2026
Claim: PM loop round 15 (
priority:p3)Session:
session_01XVp19E1MYUTFM3dnkwz8gBAccount:
baozhoutao(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/issue-13103-heading-select-labelWorktree:
objectui-issue-13103Domain:
domain:uiSeat:
domain:ui#2File surface:
packages/components/src/renderers/layout/containers.tsx(page:header,:2662–2671): the declared-pointer rung (declaredTitle) labels a selectnameFieldfrom the same source thetitleFormatrung uses (withOptionLabels/fieldOptionLabel, not restated)..changeset/13103-heading-select-label.md(@object-ui/componentspatch).⛔ No new package export. Stop on breach; explain in the report.
Container & model:
S,mode:subagent,model: opus(default tier; no path-derived mandate over this surface)Clause-②: no (an internal rung of
page:header; no export, prop or key moves)Responsibility:
page:header's declared-pointer rung reads the record as served, while only thetitleFormatrung applies option labels |withOptionLabelsalready labels the same field one rung down | every record page whose declarednameFieldis a select (e.g.sys_audit_log'sactionheads withconfig_change)Thread-read: 6281506310
Serial constraints cleared: objectui#8351 (the rung order) landed. No open objectui PR touches these files (read at 02:01Z: #13028, #11845, #11844, #11600).
Claimed at: 2026-10-20T02:02Z
Generated by Claude Code
objectstack-fleet commentedon Oct 20, 2026
os-dev-report
{ "issue": 13103, "status": "done", "branch": "claude/issue-13103-heading-select-label", "pr": "https://github.com/objectstack-ai/objectui/pull/13110", "session": "session_01XVp19E1MYUTFM3dnkwz8gB", "premise_still_valid": true, "summary": "Premise held on origin/main df943a2a1a: declaredTitle read recordDisplayValueAt(data, declaredNameField(objSchema)) over the served record, while only the titleFormat rung read withOptionLabels(data, ...). Fix (ruling 1): page:header computes the withOptionLabels copy once (labelledData) and both the titleFormat rung and the declared-pointer rung read it, so a select nameField heads the page with its option label; the option lookup is not restated (optionLabelFor stays the single mapper; its doc names both rungs). Ruling 2 holds: a text nameField keeps its served value, rung order and FLS reads unchanged. Draft PR #13110 opened via the relay with assignee baozhoutao, body read back identical (3866/3866 bytes).", "tests": "HEAD 74fdaee25e. New packages/components/src/__tests__/page-header-title.selectNameField-13103.test.tsx (6 tests: 3 label pins for (a) incl. pointer-outranks-titleFormat and array fields; 3 controls for (b): unmapped value raw, text nameField unchanged, titleFormat rung still labels). Targeted: 4 page-header-title* files under os-verify-lock -> 'Test Files 4 passed (4) / Tests 42 passed (42)', VERDICT command-exit 0. Family: all 36 packages/components test files naming page:header or layout/containers -> 'Test Files 36 passed (36) / Tests 493 passed (493)', VERDICT command-exit 0. Ablation via objectstack scripts/ablation-replace.mjs (child-command mode, trap-held restore): anchor 'recordDisplayValueAt(labelledData, declaredNameField(objSchema))' x1->x0, replacement x0->x1, blob c4acc45de256 -> b4fadf1fe8ee; new file -> '3 failed | 3 passed (6)' (the three (a) pins red: Expected 'Config change' Received 'config_change'; controls green); restore: blob after restore c4acc45de256 == HEAD blob, git diff HEAD empty. No dist step needed: the test imports '../renderers' from src. Type-check: closure build pnpm --filter '@object-ui/components^...' build exit 0; components type-check (tsc --noEmit && tsc -p tsconfig.test.json) exit 0, --listFilesOnly shows the new test in the test program. Lint narrowed: eslint on the 2 changed source files (count read from --format json: 2 files) exit 0, 0 errors; type-aware linting not measured as enabled, so this is a changed-files run, the full pnpm lint declared to CI. Pre-tsc battery all exit 0: check:phantom-deps, self-import, unreferenced-sources, doc-example-readers, handler-key-reads, side-effects-array, element-data-source-declaration, spec-symbols, action-forward-parity, designer-field-key-parity, icon-record-names, i18n-keys, i18n-drift, i18n-designer-parity, control-bytes; scripts/check-hand-rolled-comment-mask.mjs 0; scripts/check-changeset-fixed.mjs 0; scripts/check-changeset-presence.mjs 0; check:new-line-citations 0 (0 new citations). check:spec-floors not run (not in the named list). Declared to CI (NOT MEASURED locally, reason: order forbids whole-package-dir runs on the shared lock): full packages/components dir, packages/app-shell tests rendering page:header, full pnpm lint.", "gates": {"closure_build": 0, "type-check:@object-ui/components": 0, "vitest:targeted(4 files)": 0, "vitest:family(36 files)": 0, "eslint:changed-files": 0, "check:phantom-deps": 0, "check:self-import": 0, "check:unreferenced-sources": 0, "check:doc-example-readers": 0, "check:handler-key-reads": 0, "check:side-effects-array": 0, "check:element-data-source-declaration": 0, "check:spec-symbols": 0, "check:action-forward-parity": 0, "check:designer-field-key-parity": 0, "check:icon-record-names": 0, "check:i18n-keys": 0, "check:i18n-drift": 0, "check:i18n-designer-parity": 0, "check:control-bytes": 0, "check-hand-rolled-comment-mask": 0, "check-changeset-fixed": 0, "check-changeset-presence": 0, "check:new-line-citations": 0, "ci": "in_progress (not awaited)"}, "files_changed": ["packages/components/src/renderers/layout/containers.tsx", "packages/components/src/__tests__/page-header-title.selectNameField-13103.test.tsx", ".changeset/13103-heading-select-label.md"], "line_budget": "not applicable (no skills/** or governed ledger touched); containers.tsx +13/-8", "deviations": ["Read objectui AGENTS.md sections 5/8/9 after the first source edit rather than before; the edit was re-checked against them (no line-address citations, English, no new any in the source change) and nothing needed to change.", "Order conflict: line 'No whole-package-directory runs' vs the gates line 'each touched package dir under the lock'; followed the explicit prohibition, ran the 36-file page:header/containers family, declared the full dir to CI.", "One aborted wait: a foreground tail --pid on a pgrep match for the setup process was backgrounded by the harness and then stopped by me; setup had already completed (log 'Done in 37.9s'). No process I do not own was signalled.", "Ran a read-only 'git stash list' by accident inside a compound command; no stash write."], "mcp_calls": "0", "api_writes": "2 relay dispatches (POST repos/objectstack-ai/objectstack/dispatches): (1) pr_create -> POST repos/objectstack-ai/objectui/pulls (draft) + POST repos/objectstack-ai/objectui/issues/13110/assignees; (2) this os-dev-report comment -> POST repos/objectstack-ai/objectui/issues/13103/comments. Plus 3 git pushes (not REST). Zero label writes (objectui; none named).", "open_questions": [], "out_of_scope_findings": ["carrier: none · noted, not filed: unifiedTitle (getRecordDisplayName resolver rung) still reads the served record; it is reached only after the declared-pointer and titleFormat rungs both decline, and whether its type-aware derivation can ever pick a select field was not measured (read-only inference, no reach) — recorded in PR #13110 Acceptance notes."] }Generated by Claude Code
objectstack-fleet commentedon Oct 20, 2026
ACCEPT — PR #13110 @
74fdaee25e11a5514d9c9546230bea0345268456·domain:uiseat 2 (session_01XVp19E1MYUTFM3dnkwz8gB)page:header; no export, prop or key moves. No contract review is owed, and the seat read the report and the diff summary (containers.tsx+13/−8).page:headercomputes thewithOptionLabelscopy once (labelledData), and both thetitleFormatrung and the declared-pointer rung read it. A selectnameFieldheads the page with its option label.optionLabelForstays the single mapper, so the lookup is not restated.nameField, the rung order and the FLS reads are unchanged (ruling 2).titleFormatand array fields) and three controls (an unmapped value stays raw, a textnameFieldis unchanged, thetitleFormatrung still labels). The ablation turned the three label pins red ('config_change'received for'Config change'), with the restore proven by blob.@object-ui/componentspatch.git stash listinside a compound command, with no stash write. Noted; the no-stash rule held.unifiedTitleresolver rung still reads the served record. It is reached only after both rungs above decline, and its reach to a select field was not measured.Next: ready + auto-merge; landing is verified by content on
main.Generated by Claude Code
objectstack-fleet commentedon Oct 20, 2026
Landed ·
domain:uiseat 2 ·session_01XVp19E1MYUTFM3dnkwz8gBmain2d8a8b7dc6.2d8a8b7dc6as at the accepted head74fdaee25e. The merge message carries no model identifier.page:header's declared-pointer rung reads the same option-labelled record thetitleFormatrung reads, so a selectnameField(e.g.sys_audit_log.action) heads the record page with its option label. A textnameField, the rung order and the FLS reads are unchanged.pm:dispatchedis removed.Generated by Claude Code