Filed on the maintainer's ruling (2026-08-31, hotcrm#1247 adjudication, verbatim: 「#1247 也是平台的问题吧。元数据应用不应该考虑这些细节。」).
The mechanism (measured across hotcrm#1247 / objectstack#11289 / shipped bundle)
record:details hides empty fields, then RecordDetailsRenderer (packages/plugin-detail/src/renderers/record-details.tsx) maps every section with hideEmpty: s.hideEmpty ?? true, and DetailSection returns null when all fields are empty. On a hand-created sparse record the body collapses to a degenerate two rows (hotcrm opportunity: 7 optional body fields, 5 empty; case page: case number + three empty rows) — while seeded demo data masks it.
⭐ The platform already knows the right behavior and says so in its own code — DetailSection's heuristic comment: "If a section is entirely empty (e.g., loading state, brand-new record), do NOT auto-hide — the labels themselves are useful as a structural skeleton." The renderer's forced ?? true overrides exactly that case. objectstack PR #11662 then made hideEmpty an AUTHORABLE opt-out — which is the shape the maintainer has now ruled against: every app hand-writing hideEmpty: false per section to avoid looking broken is per-app tax (objectstack#13848 principles).
Deliverable
- Flip the default: stop forcing
hideEmpty ?? true in RecordDetailsRenderer; let DetailSection's stated heuristic own the all-empty case — an empty section keeps its heading and field labels (empty-value placeholders per the design system), so a sparse record renders a full structural skeleton with ZERO app-side authoring; - authored
hideEmpty: true (declared by objectstack PR #11662) remains fully honoured as the explicit opt-in to hiding — the key's meaning is unchanged, only the unauthored default flips; - changeset marks the behavior change (apps relying on auto-hide of unauthored sections will now show skeletons — the ruled loud-over-silent direction); name any reference-app hits in the PR.
Acceptance scenario
hotcrm opportunity_detail_page and case_detail_page on hand-created records with only required fields: full section skeletons render (no two-row body, no vanished sections), with zero hotcrm-side changes. The strip-vs-body field re-allocation hotcrm#1247 contemplated becomes unnecessary and is NOT performed.
Refs: hotcrm#1247 (closed with pointer here) · objectstack#11289 / PR #11662 (key declaration half) · objectstack#13848 (application-repo principles) · objectui#7063 (sibling ruling: dashboard widget default empty state — same principle, different surface).
Filed on the maintainer's ruling (2026-08-31, hotcrm#1247 adjudication, verbatim: 「#1247 也是平台的问题吧。元数据应用不应该考虑这些细节。」).
The mechanism (measured across hotcrm#1247 / objectstack#11289 / shipped bundle)
record:detailshides empty fields, thenRecordDetailsRenderer(packages/plugin-detail/src/renderers/record-details.tsx) maps every section withhideEmpty: s.hideEmpty ?? true, andDetailSectionreturnsnullwhen all fields are empty. On a hand-created sparse record the body collapses to a degenerate two rows (hotcrm opportunity: 7 optional body fields, 5 empty; case page: case number + three empty rows) — while seeded demo data masks it.⭐ The platform already knows the right behavior and says so in its own code —
DetailSection's heuristic comment: "If a section is entirely empty (e.g., loading state, brand-new record), do NOT auto-hide — the labels themselves are useful as a structural skeleton." The renderer's forced?? trueoverrides exactly that case. objectstack PR #11662 then madehideEmptyan AUTHORABLE opt-out — which is the shape the maintainer has now ruled against: every app hand-writinghideEmpty: falseper section to avoid looking broken is per-app tax (objectstack#13848 principles).Deliverable
hideEmpty ?? trueinRecordDetailsRenderer; letDetailSection's stated heuristic own the all-empty case — an empty section keeps its heading and field labels (empty-value placeholders per the design system), so a sparse record renders a full structural skeleton with ZERO app-side authoring;hideEmpty: true(declared by objectstack PR #11662) remains fully honoured as the explicit opt-in to hiding — the key's meaning is unchanged, only the unauthored default flips;Acceptance scenario
hotcrm
opportunity_detail_pageandcase_detail_pageon hand-created records with only required fields: full section skeletons render (no two-row body, no vanished sections), with zero hotcrm-side changes. The strip-vs-body field re-allocation hotcrm#1247 contemplated becomes unnecessary and is NOT performed.Refs: hotcrm#1247 (closed with pointer here) · objectstack#11289 / PR #11662 (key declaration half) · objectstack#13848 (application-repo principles) · objectui#7063 (sibling ruling: dashboard widget default empty state — same principle, different surface).