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.
record:details draws a read-only boolean as text (开启 / 关闭), not a disabled checkbox that reads as a broken setting (ruling B on cloud#2774 Q3) #12933
Filed by the director seat (summon #43 continuation 4, session_01QJC7i981TSs9L1CGJK59Ax) on the maintainer's ruling Q3 B on objectstack-ai/cloud#2774 (batch #362 item 5, 「其他同意」; the ruling record is that card's Ruled: line) under the standing 口径 「平台相关的功能,应该尽量先改平台」. ⛔ Not a claim. Filing gate ①: a measured usability defect on every record page.
What is measured (cloud#2916 Target 2, the cloud seat's reading on the pin)
record:details lists fields by name (spec component.zod.ts:1357); a read-only boolean renders as the console's checkbox, which the 2026-10-16 walk read as 「a setting that cannot be clicked」 on the environment detail's 访问与登录 section. The empty-field fold is DetailSection's own (objectui#7129 Q2-C) and stays.
Scope
In record:details, a boolean field the viewer cannot edit draws as text (开启 / 关闭, i18n), not as a disabled checkbox; editable booleans unchanged.
The empty-field fold is unchanged (objectui#7129 Q2-C).
Clause-②: no.
Done when
A test: a read-only boolean in a details section renders the text; an editable one renders the control.
cloud#2916 Target 2's section can be declared as written.
Claim: PM loop round 4 (priority:p2)
Session: session_01XVp19E1MYUTFM3dnkwz8gB
Account: baozhoutao (the seat's linked user as GET /user answers it; the card's assignee)
Branch: claude/issue-12933-readonly-boolean-text
Worktree: objectui-issue-12933
Domain: domain:ui
Seat: domain:ui#2
File surface: packages/plugin-detail/src/DetailSection.tsx (the read-display branch of renderField, for a boolean / toggle field the viewer cannot edit), and tests beside it. Plus one .changeset/12933-*.md for @object-ui/plugin-detail. Stop on breach; explain in the report.
Container & model: S, mode:subagent, model: opus (default tier; dispatch-gates --tier --repo objectstack-ai/objectui reads no path-derived mandate)
Clause-②: no
Responsibility: @object-ui/plugin-detail's DetailSection read display routes a boolean through BooleanCellRenderer (a checkbox face) | the platform already has a boolean-as-text read face, @object-ui/fields' BooleanValueText / useBooleanValueLabel (common.yes / common.no), used by the read-only form widgets | every viewer of a record page with a read-only boolean; cloud#2916's environment detail is the named consumer.
Seat ruling (no-escalation class, reuse over a second dialect): the text face is the existing BooleanValueText word pair, reused. The card's 开启 / 关闭 is read as the shape (text, i18n), not as a new key pair; a second boolean word pair would be a second dialect for one value class. A non-boolean value keeps the shared "No value" affordance (objectui#8582). Recorded so the director can overrule.
Thread-read: none
Serial constraints cleared: no open objectui PR touches DetailSection.tsx. The lane's in-flight claims are disjoint: objectui#12924 (deriveMasterDetail.ts, GridField.tsx, i18n packs) and objectui#12490 (ApprovalsInboxPage.tsx). objectui#12923 (the read-only GridField cell routing) has merged.
Claimed at: 2026-10-18T04:26Z
{
"issue": 12933,
"status": "done",
"branch": "claude/issue-12933-readonly-boolean-text",
"pr": "https://github.com/objectstack-ai/objectui/pull/12935",
"session": "session_01XVp19E1MYUTFM3dnkwz8gB",
"premise_still_valid": true,
"summary": "DetailSection's read display now draws a boolean/toggle the viewer cannot edit as the locale word via @object-ui/fields useBooleanValueLabel (common.yes / common.no) instead of BooleanCellRenderer's disabled checkbox; routed by renderer identity (CellRenderer === BooleanCellRenderer) and only for typeof value === 'boolean', so a non-boolean still hits the renderer's objectui#8582 guard ('No value') and editable booleans keep the checkbox. A1: 'cannot edit' = the existing per-field fieldEditable (view readonly, object-def readonly, computed/system/inline-excluded types, caller's field write grant); named gap: the record-level recordEdit affordance / authored inlineEdit:false reach DetailSection only as presence of onEnterInlineEdit, which is also absent when a host just doesn't wire inline edit, so it is not used. A2: HeaderHighlight already draws booleans as a word chip on its own path, unchanged. Premise correction: BooleanValueText is NOT exported from @object-ui/fields (index comment says it stays internal); used the exported useBooleanValueLabel (same word pair, no new export, Clause-2 stays no).",
"tests": "All on head dd56fb9c0a. New DetailSection.readonlyBooleanText-12933.test.tsx: 'Test Files 1 passed (1) / Tests 7 passed (7)' (lock VERDICT command-exit 0). Ablation via objectstack scripts/ablation-replace.mjs (anchor x1 to x0, blob 7c3677750082 to c60181013ce5; source import, no dist in path): 'Tests 4 failed | 3 passed (7)', the 4 = read-only word cases (view/object x en/zh-CN); restore: blob == HEAD 7c3677750082, git diff HEAD empty. Named families (89 files naming DetailSection / BooleanCellRenderer / BooleanValueText / useBooleanValueLabel): plugin-detail 'Test Files 60 passed (60) / Tests 673 passed (673)'; others 'Test Files 29 passed (29) / Tests 536 passed (536)'. Closure build turbo --filter='@object-ui/plugin-detail^...' 11/11 tasks exit 0; pnpm --filter @object-ui/plugin-detail run type-check exit 0 (script echoed; new test in tsconfig.test.json program, --listFiles count 1). Lint narrowed: eslint --no-inline-config --format json on the 2 changed sources = 2 files, 0 errors, 12 pre-existing warnings off the diff; eslint.config.js has no parserOptions.project/projectService so not type-aware, untouched files' verdicts cannot move. Full packages/plugin-detail/ dir declared to CI.",
"gates": "exit 0 each: check:phantom-deps, check:self-import, check:unreferenced-sources, check:doc-example-readers, check:handler-key-reads, check:side-effects-array, check:element-data-source-declaration, check:spec-symbols, check:action-forward-parity, check:designer-field-key-parity, check:icon-record-names, check:i18n-keys, check:i18n-drift, check:i18n-designer-parity, check:control-bytes, check-hand-rolled-comment-mask.mjs, check-changeset-fixed.mjs, check-changeset-presence.mjs (1 changeset declared); type-check 0; targeted vitest 0; lint 0. NOT MEASURED locally: whole packages/plugin-detail dir (declared to CI per order). CI: in_progress at report time.",
"line_budget": "n/a — no skills/** or ledger touched; diff +27/-0 in DetailSection.tsx (code + comment), new test file, changeset",
"files_changed": ["packages/plugin-detail/src/DetailSection.tsx", "packages/plugin-detail/src/__tests__/DetailSection.readonlyBooleanText-12933.test.tsx", ".changeset/12933-readonly-boolean-text.md"],
"deviations": ["Order's ruling named BooleanValueText 'exported from @object-ui/fields'; it is not exported — used the exported useBooleanValueLabel (same formatter) rather than add an export outside the file surface.", "Order said zh-CN: pinned with defaultLanguage 'zh-CN' through a real I18nProvider (resolves to the zh pack: 是 / 否).", "Labels: zero writes (objectui, order named none); plugin/tests labels on the PR came from labeler.yml."],
"mcp_calls": "0",
"api_writes": "2 — fleet-write relay dispatches: (1) pr_create so POST /repos/objectstack-ai/objectui/pulls (draft) + POST /repos/objectstack-ai/objectui/issues/12935/assignees [baozhoutao], read-back 5691 bytes identical; (2) comment so POST /repos/objectstack-ai/objectui/issues/12933/comments (this report). Plus 2 git pushes (not REST).",
"open_questions": [],
"out_of_scope_findings": ["carrier: none (承接者:无) · A1 gap: record-level 'viewer cannot update this object' is indistinguishable inside DetailSection from 'host did not wire inline edit' (both = no onEnterInlineEdit); a boolean on such an object with no field-level readonly/denial still draws the checkbox · noted in PR Acceptance notes, not filed", "carrier: none (承接者:无) · HeaderHighlight boolean chip reads value by truthiness on resolvedType === 'boolean' (non-boolean stored value would draw the Yes chip; toggle not matched) · source read only, no public-door reach measured · noted in PR Acceptance notes, not filed · dedupe words: HeaderHighlight boolean truthiness, highlights chip non-boolean, toggle highlight"]
}
PR #12935 at head dd56fb9, reviewed against the claim 6245642429 and the dev report 6245812624.
What changed: in DetailSection's read display, a boolean or toggle whose row is not editable (fieldEditable false: the field's or the object definition's readonly, a computed / system / inline-excluded type, or no field write grant) draws the locale's word through @object-ui/fields' exported useBooleanValueLabel (common.yes / common.no), not BooleanCellRenderer's disabled checkbox. The branch matches the renderer by identity, so toggle reads the same and a host's own boolean face is kept. A non-boolean value still reaches the renderer's objectui#8582 guard ("No value"); an editable boolean keeps its checkbox; inline edit and the empty-field fold are unchanged.
Seat ruling held: one word pair, no new keys. The claim's BooleanValueText turned out to be internal to @object-ui/fields; the dev used the exported hook behind it rather than add an export. No prop, export or key moves.
Clause-②:no, confirmed by the diff. No contract review owed (no published surface changes, and nothing narrows).
Tests:DetailSection.readonlyBooleanText-12933.test.tsx (7 tests) pins read-only words for a view-level and an object-level readonly in en and zh-CN (是 / 否), the editable checkbox, and the non-boolean "No value". Ablation: reverting the routing turns exactly the 4 read-only word cases red; the restore was proven by blob hash. The families naming these symbols pass (plugin-detail 60 files / 673 tests; other packages 29 files / 536 tests). Type-check and the pre-tsc battery exit 0. The full packages/plugin-detail/ directory is declared to CI.
Acceptance notes, not filed:
Inside DetailSection, a record the viewer cannot update looks the same as one whose host did not wire inline edit (onEnterInlineEdit absent in both). A boolean on such an object, with no field-level readonly or denied grant, still draws the checkbox. Recorded on the PR; not a defect class this seat files without a measured reach.
HeaderHighlight's boolean chip reads by truthiness on resolvedType === 'boolean'. Read from source only, with no reach measured through a public entry, so not filed.
Line count: +157 / −0 across 3 files (measured numstat; the report comment's +27 for DetailSection.tsx is a typo for the measured +21).
Trailers: the one commit carries only the model-free pair.
CI at head: all 36 check-runs on dd56fb9 are complete: 33 success, 3 skipped (dependabot and the two coverage jobs), none failed; mergeable_state: clean. Path surface (3 files, +157 / −0): packages/plugin-detail/src/** and one changeset, no governed path.
PR #12935 merged through the merge queue as 79cb8c03ebb98a387cc1755cf6996dc18fb2f128, which is on main; Fixes #12933 closes this card. Verified by content: all 3 of the PR's files on main are blob-identical to the accepted head dd56fb9. The merge commit's message names no model.
What landed:
In record:details, a boolean or toggle the viewer cannot edit (field or object-definition readonly, a computed / system / inline-excluded type, or no field write grant) reads as the locale's word (common.yes / common.no: Yes / No, 是 / 否) instead of a disabled checkbox. An editable boolean keeps its checkbox; a non-boolean value still draws "No value". @object-ui/plugin-detail: patch, no new key or export.
For cloud: objectstack-ai/cloud#2916 Target 2's 访问与登录 section can be declared as written once objectstack's .objectui-sha covers the merge commit above. The words are the shared yes / no pair rather than 开启 / 关闭 (the claim's seat ruling); a different pair is the director's call if wanted. This seat now removes pm:dispatched.
Activity
objectstack-fleet commentedon Oct 18, 2026
Claim: PM loop round 4 (
priority:p2)Session:
session_01XVp19E1MYUTFM3dnkwz8gBAccount:
baozhoutao(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/issue-12933-readonly-boolean-textWorktree:
objectui-issue-12933Domain:
domain:uiSeat:
domain:ui#2File surface:
packages/plugin-detail/src/DetailSection.tsx(the read-display branch ofrenderField, for a boolean / toggle field the viewer cannot edit), and tests beside it. Plus one.changeset/12933-*.mdfor@object-ui/plugin-detail. Stop on breach; explain in the report.Container & model:
S,mode:subagent,model: opus(default tier;dispatch-gates --tier --repo objectstack-ai/objectuireads no path-derived mandate)Clause-②: no
Responsibility:
@object-ui/plugin-detail'sDetailSectionread display routes a boolean throughBooleanCellRenderer(a checkbox face) | the platform already has a boolean-as-text read face,@object-ui/fields'BooleanValueText/useBooleanValueLabel(common.yes/common.no), used by the read-only form widgets | every viewer of a record page with a read-only boolean; cloud#2916's environment detail is the named consumer.Seat ruling (no-escalation class, reuse over a second dialect): the text face is the existing
BooleanValueTextword pair, reused. The card's 开启 / 关闭 is read as the shape (text, i18n), not as a new key pair; a second boolean word pair would be a second dialect for one value class. A non-boolean value keeps the shared "No value" affordance (objectui#8582). Recorded so the director can overrule.Thread-read: none
Serial constraints cleared: no open objectui PR touches
DetailSection.tsx. The lane's in-flight claims are disjoint: objectui#12924 (deriveMasterDetail.ts,GridField.tsx, i18n packs) and objectui#12490 (ApprovalsInboxPage.tsx). objectui#12923 (the read-onlyGridFieldcell routing) has merged.Claimed at: 2026-10-18T04:26Z
objectstack-fleet commentedon Oct 18, 2026
os-dev-report
{ "issue": 12933, "status": "done", "branch": "claude/issue-12933-readonly-boolean-text", "pr": "https://github.com/objectstack-ai/objectui/pull/12935", "session": "session_01XVp19E1MYUTFM3dnkwz8gB", "premise_still_valid": true, "summary": "DetailSection's read display now draws a boolean/toggle the viewer cannot edit as the locale word via @object-ui/fields useBooleanValueLabel (common.yes / common.no) instead of BooleanCellRenderer's disabled checkbox; routed by renderer identity (CellRenderer === BooleanCellRenderer) and only for typeof value === 'boolean', so a non-boolean still hits the renderer's objectui#8582 guard ('No value') and editable booleans keep the checkbox. A1: 'cannot edit' = the existing per-field fieldEditable (view readonly, object-def readonly, computed/system/inline-excluded types, caller's field write grant); named gap: the record-level recordEdit affordance / authored inlineEdit:false reach DetailSection only as presence of onEnterInlineEdit, which is also absent when a host just doesn't wire inline edit, so it is not used. A2: HeaderHighlight already draws booleans as a word chip on its own path, unchanged. Premise correction: BooleanValueText is NOT exported from @object-ui/fields (index comment says it stays internal); used the exported useBooleanValueLabel (same word pair, no new export, Clause-2 stays no).", "tests": "All on head dd56fb9c0a. New DetailSection.readonlyBooleanText-12933.test.tsx: 'Test Files 1 passed (1) / Tests 7 passed (7)' (lock VERDICT command-exit 0). Ablation via objectstack scripts/ablation-replace.mjs (anchor x1 to x0, blob 7c3677750082 to c60181013ce5; source import, no dist in path): 'Tests 4 failed | 3 passed (7)', the 4 = read-only word cases (view/object x en/zh-CN); restore: blob == HEAD 7c3677750082, git diff HEAD empty. Named families (89 files naming DetailSection / BooleanCellRenderer / BooleanValueText / useBooleanValueLabel): plugin-detail 'Test Files 60 passed (60) / Tests 673 passed (673)'; others 'Test Files 29 passed (29) / Tests 536 passed (536)'. Closure build turbo --filter='@object-ui/plugin-detail^...' 11/11 tasks exit 0; pnpm --filter @object-ui/plugin-detail run type-check exit 0 (script echoed; new test in tsconfig.test.json program, --listFiles count 1). Lint narrowed: eslint --no-inline-config --format json on the 2 changed sources = 2 files, 0 errors, 12 pre-existing warnings off the diff; eslint.config.js has no parserOptions.project/projectService so not type-aware, untouched files' verdicts cannot move. Full packages/plugin-detail/ dir declared to CI.", "gates": "exit 0 each: check:phantom-deps, check:self-import, check:unreferenced-sources, check:doc-example-readers, check:handler-key-reads, check:side-effects-array, check:element-data-source-declaration, check:spec-symbols, check:action-forward-parity, check:designer-field-key-parity, check:icon-record-names, check:i18n-keys, check:i18n-drift, check:i18n-designer-parity, check:control-bytes, check-hand-rolled-comment-mask.mjs, check-changeset-fixed.mjs, check-changeset-presence.mjs (1 changeset declared); type-check 0; targeted vitest 0; lint 0. NOT MEASURED locally: whole packages/plugin-detail dir (declared to CI per order). CI: in_progress at report time.", "line_budget": "n/a — no skills/** or ledger touched; diff +27/-0 in DetailSection.tsx (code + comment), new test file, changeset", "files_changed": ["packages/plugin-detail/src/DetailSection.tsx", "packages/plugin-detail/src/__tests__/DetailSection.readonlyBooleanText-12933.test.tsx", ".changeset/12933-readonly-boolean-text.md"], "deviations": ["Order's ruling named BooleanValueText 'exported from @object-ui/fields'; it is not exported — used the exported useBooleanValueLabel (same formatter) rather than add an export outside the file surface.", "Order said zh-CN: pinned with defaultLanguage 'zh-CN' through a real I18nProvider (resolves to the zh pack: 是 / 否).", "Labels: zero writes (objectui, order named none); plugin/tests labels on the PR came from labeler.yml."], "mcp_calls": "0", "api_writes": "2 — fleet-write relay dispatches: (1) pr_create so POST /repos/objectstack-ai/objectui/pulls (draft) + POST /repos/objectstack-ai/objectui/issues/12935/assignees [baozhoutao], read-back 5691 bytes identical; (2) comment so POST /repos/objectstack-ai/objectui/issues/12933/comments (this report). Plus 2 git pushes (not REST).", "open_questions": [], "out_of_scope_findings": ["carrier: none (承接者:无) · A1 gap: record-level 'viewer cannot update this object' is indistinguishable inside DetailSection from 'host did not wire inline edit' (both = no onEnterInlineEdit); a boolean on such an object with no field-level readonly/denial still draws the checkbox · noted in PR Acceptance notes, not filed", "carrier: none (承接者:无) · HeaderHighlight boolean chip reads value by truthiness on resolvedType === 'boolean' (non-boolean stored value would draw the Yes chip; toggle not matched) · source read only, no public-door reach measured · noted in PR Acceptance notes, not filed · dedupe words: HeaderHighlight boolean truthiness, highlights chip non-boolean, toggle highlight"] }Generated by Claude Code
objectstack-fleet commentedon Oct 18, 2026
ACCEPT ·
domain:uiseat 2 ·session_01XVp19E1MYUTFM3dnkwz8gB· 2026-10-18T05:00ZPR #12935 at head
dd56fb9, reviewed against the claim6245642429and the dev report6245812624.DetailSection's read display, a boolean or toggle whose row is not editable (fieldEditablefalse: the field's or the object definition'sreadonly, a computed / system / inline-excluded type, or no field write grant) draws the locale's word through@object-ui/fields' exporteduseBooleanValueLabel(common.yes/common.no), notBooleanCellRenderer's disabled checkbox. The branch matches the renderer by identity, sotogglereads the same and a host's own boolean face is kept. A non-boolean value still reaches the renderer's objectui#8582 guard ("No value"); an editable boolean keeps its checkbox; inline edit and the empty-field fold are unchanged.BooleanValueTextturned out to be internal to@object-ui/fields; the dev used the exported hook behind it rather than add an export. No prop, export or key moves.no, confirmed by the diff. No contract review owed (no published surface changes, and nothing narrows).DetailSection.readonlyBooleanText-12933.test.tsx(7 tests) pins read-only words for a view-level and an object-levelreadonlyin en and zh-CN (是 / 否), the editable checkbox, and the non-boolean "No value". Ablation: reverting the routing turns exactly the 4 read-only word cases red; the restore was proven by blob hash. The families naming these symbols pass (plugin-detail 60 files / 673 tests; other packages 29 files / 536 tests). Type-check and the pre-tsc battery exit 0. The fullpackages/plugin-detail/directory is declared to CI.DetailSection, a record the viewer cannot update looks the same as one whose host did not wire inline edit (onEnterInlineEditabsent in both). A boolean on such an object, with no field-level readonly or denied grant, still draws the checkbox. Recorded on the PR; not a defect class this seat files without a measured reach.HeaderHighlight's boolean chip reads by truthiness onresolvedType === 'boolean'. Read from source only, with no reach measured through a public entry, so not filed.+27forDetailSection.tsxis a typo for the measured+21).dd56fb9are complete: 33 success, 3 skipped (dependabot and the two coverage jobs), none failed;mergeable_state: clean. Path surface (3 files, +157 / −0):packages/plugin-detail/src/**and one changeset, no governed path.Next:
pr_ready+automerge_enable.Generated by Claude Code
objectstack-fleet commentedon Oct 18, 2026
Landed ·
domain:uiseat 2 ·session_01XVp19E1MYUTFM3dnkwz8gB· 2026-10-18T05:14ZPR #12935 merged through the merge queue as
79cb8c03ebb98a387cc1755cf6996dc18fb2f128, which is onmain;Fixes #12933closes this card. Verified by content: all 3 of the PR's files onmainare blob-identical to the accepted headdd56fb9. The merge commit's message names no model.What landed:
record:details, a boolean or toggle the viewer cannot edit (field or object-definitionreadonly, a computed / system / inline-excluded type, or no field write grant) reads as the locale's word (common.yes/common.no: Yes / No, 是 / 否) instead of a disabled checkbox. An editable boolean keeps its checkbox; a non-boolean value still draws "No value".@object-ui/plugin-detail: patch, no new key or export.For cloud: objectstack-ai/cloud#2916 Target 2's 访问与登录 section can be declared as written once objectstack's
.objectui-shacovers the merge commit above. The words are the shared yes / no pair rather than 开启 / 关闭 (the claim's seat ruling); a different pair is the director's call if wanted. This seat now removespm:dispatched.Generated by Claude Code
fix(plugin-detail): draw a read-only boolean as text in record:details (