Repository navigation
metadata-admin previews: render an app area's description, each RLS policy's label / description, and a view container's label #11027
Description
Activity
objectstack-fleet commented
on Sep 29, 2026 ContributorAuthorMore actionsPath: changing a running app without code — the designer shows what the author wrote | 缺项 (four authored display keys no preview renders) | P3
Triage: first grade —
enhancement·priority:p3·domain:ui·area:studio·pm:queue. The objectui end of objectstack-ai/objectstack#20299, with its gradeTriage: lands in
packages/app-shell/src/views/metadata-admin/previews/(AppPreview.tsx,PermissionPreview.tsx,ViewPreview.tsx) ⇒domain:ui. It is the layer sub-issue of objectstack-ai/objectstack#20299 (p3, ENFORCE, grade5859600931), so it takes the parent's grade.Triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-09-29T00:54Z. ⛔ Not a claim, ⛔ not a dispatch.Direction: as the card states.
- Render the four keys where a human sees them. An unauthored key renders nothing: no invented fallback text.
- The
viewcontainerlabelgoes somewhere visible, such as the preview heading. ⛔ Don't bring back a tab strip for one entry to show it. - Preview chrome goes through the designer locale.
flow.description,hook.label/hook.descriptionand aHookPreviewstay out, as the card says:ResourceListPage's default columns already show them.- Pins: one per preview, with authored and absent cases.
- addedarea:studioChanging a running app without code — authoring, publish, docs and the portalChanging a running app without code — authoring, publish, docs and the portaldomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatobjectui ui stream: fix lands on the published library or apps — objectui execution seatenhancementNew feature or requestNew feature or requestand removed
on Sep 29, 2026 objectstack-fleet commented
on Sep 29, 2026 ContributorAuthorMore actionsClaim: PM loop round 2 —
domain:uiexecution seat 2
Session:session_011p7ikEivgXefNDaE5S5Uec
Account:os-support-ai(the seat's linked user asGET /useranswers it; the card's assignee)
Branch:claude/issue-11027-preview-display-keys
Worktree:objectui-issue-11027
Domain:domain:ui
Seat:domain:ui#2
File surface (triage5881560418: as the card states):packages/app-shell/src/views/metadata-admin/previews/AppPreview.tsx: each area'sdescriptionbeside its label.packages/app-shell/src/views/metadata-admin/previews/PermissionPreview.tsx: each RLS policy is listed with itslabelanddescription, not only the count pill (:129,:182).packages/app-shell/src/views/metadata-admin/previews/ViewPreview.tsx: theviewcontainerlabelgoes somewhere visible, such as the preview heading. ⛔ Don't bring back a tab strip for one entry.- Preview chrome goes through the designer locale. If a label needs a new pack key, it is added to the locale packs in
packages/i18n(free: seat 1's objectui#11056 has merged). - Pins: one per preview, with authored and absent cases (an unauthored key renders nothing: no invented fallback text). One changeset (
'@object-ui/app-shell': patch, plus@object-ui/i18nif a key is added).
⛔
flow.description,hook.label/hook.descriptionand aHookPreviewstay out (ResourceListPage's default columns already show them). ⛔ No change to objectstack's liveness ledger (the parent objectstack-ai/objectstack#20299 keeps it).
Stop on breach; explain in the report.
Container & model:S,mode:subagent,model: opus(TIER_DEFAULT;dispatch-gates --tier --repo objectstack-ai/objectuiover this surface: no path-derived mandate, at objectstack288611e3)
Clause-②: no
Why no: three Studio previews start rendering keys the spec already publishes; no type, schema, export or accept set moves.
Thread-read: 5881560418
Serial constraints cleared: read 2026-09-29T11:39Z at objectuiorigin/maina5841be35.- Open PRs: by their file lists, none of objectui#11087, chore(deps): resolve @objectstack/* 17.5.0, and the zod 4.6.5 it requires, in pnpm-lock.yaml (objectui#11073) #11086, feat(cli):
objectui validateandobjectui checkjudge through the strict authoring face (objectui#5250, slice A) #11069 and feat(plugin-grid): one display page size read from the spec, and a distinct fetch batch (objectui#9853) #10278 touchesmetadata-admin/previews/or the locale packs. - In-flight branches: by their three-dot diffs, none of objectui#11026, finding(plugin-form+): family — a spec ComponentPropsMap row declares I18nLabel and the objectui renderer reads it raw; object-form's seven members are the second member (a locale-map submitText throws as a React child) #10993 batch 2, finding(app-shell): Studio's flow start-node 「Platform event」 option writes a trigger kind the engine never routes, so the flow never fires #11067 and finding(plugin-form): object-form's declared
modalCloseButtonis never read, somodalCloseButton: falsestill shows the modal's close button #11061, nor seat 1's objectui#11062, touches them. - Queued behind this card: objectui#10862 (19 designer preview files, the locale packs) and objectui#11085's
previews/half, which share this directory.
Generated by Claude Code
objectstack-fleet commented
on Sep 29, 2026 ContributorAuthorMore actionsos-dev-report
{ "issue": 11027, "status": "done", "branch": "claude/issue-11027-preview-display-keys", "pr": "https://github.com/objectstack-ai/objectui/pull/11098", "session": "session_011p7ikEivgXefNDaE5S5Uec — subagent of the PM session (container CLAUDE_CODE_REMOTE_SESSION_ID cse_011p7ikEivgXefNDaE5S5Uec); identity = branch claude/issue-11027-preview-display-keys named in PM claim 5889511891", "premise_still_valid": true, "summary": "All four display keys now render in their Studio previews, measured at origin/main a5841be35 and built on it. AppPreview had 0 areas reads (control: navigation 8 hits). It now lists AppSchema.areas: each area label and id, with the description beneath when authored. Both keys are I18nLabel, resolved in the designer locale through the spec resolveI18nLabel. PermissionPreview used rowLevelSecurity only for the count pill. It now lists each policy by name, with label and description when authored, under the existing perm.rls.title heading. The empty state now also requires rowLevelSecurity to be empty, so a policies-only set shows its policies. ViewPreview draws the view label as an h3 heading on the no-object, form and list routes. It is I18nLabel, and no one-entry tab strip was added. An unauthored key renders nothing. New chrome is one designer row, engine.appPreview.areas (en Areas, zh 区域), in metadata-admin/i18n.ts. One pin per preview covers authored and absent cases, plus locale-map cases where the key type allows one; RLS label and description are plain z.string, so they have none. The draft PR is 11098, assigned to os-support-ai; the worktree is removed.", "tests": "At final head 335a6c38c, all through os-verify-lock:\n(1) Build: pnpm exec turbo run build --filter=@object-ui/app-shell^... --concurrency=2 → exit 0, 28 tasks, 12 cached.\n(2) Type-check: pnpm --filter @object-ui/app-shell type-check (tsc --noEmit && tsc -p tsconfig.test.json) → exit 0. tsc -p tsconfig.test.json --listFilesOnly lists all 3 pins.\n(3) Tests: pnpm exec vitest run --maxWorkers=2 packages/app-shell/src/views/metadata-admin/previews/ plus packages/i18n tests appDesigner-fieldDesigner-formula-retired-6310, dashboard-emptyState-keys-retired-7125 and perm-home-namespace-3546 → Test Files 82 passed (82), Tests 1108 passed (1108). That run included 1 uncommitted scratch probe (1 test), so the committed tree accounts for 81 files and 1107 tests.\n(4) Earlier, at 0edb411f1: 3 pins plus 7 sibling preview files → 10 files, 148 passed.\n(5) Reverse verification at 0edb411f1: the three preview sources were checked out at BASE a5841be35, with the pins at head. The mutation was proven on disk: each file hashed to its BASE blob, and readAreas, readPolicies and ViewLabelHeading each counted 0. Result: 11 failed, 2 passed of 13. The 2 green are the per-app no-areas and per-set no-policies absent cases, which is the expected direction. All authored, locale-map and heading cases went red, including the real object-view list route, where the base tree draws no heading for the label. Restored with git checkout HEAD under an EXIT/INT/TERM trap, proven by HEAD blob hashes and an empty git diff HEAD. The later commit 335a6c38c is type-only (draft.areas instead of an any cast; a typed stub adapter), and the reverse run was not repeated for it.\n(6) Lint narrowed to the diff: pnpm exec eslint --format json over the 7 changed ts/tsx files → 7 files, 0 errors, 29 warnings. Per-file base to head: AppPreview 8 to 8, PermissionPreview 3 to 3, ViewPreview 18 to 18, i18n.ts 0 to 0, pins 0. Population: eslint.config.js files **/*.{ts,tsx} minus the build-output ignores. Invariance: there is no parserOptions.project or projectService, so linting is not type-aware and no untouched file verdict can move. Repo-wide pnpm lint is CI.\n(7) NOT MEASURED locally: the full pnpm test and pnpm lint runs (CI), and a real browser (RTL DOM only).", "gates": [ "node scripts/check-i18n-call-site-keys.mjs exit 0 @335a6c38c", "node scripts/check-i18n-designer-table-parity.mjs exit 0 @335a6c38c (Every en row has a zh row, and every shared row carries the same placeholders.)", "node scripts/check-i18n-en-drift.mjs exit 0 @335a6c38c (designer table: 1 key added, 0 en values changed)", "node scripts/check-changeset-presence.mjs exit 0 @335a6c38c (7 source files of 1 released package, 1 changeset)", "node scripts/check-changeset-no-major.mjs exit 0 @335a6c38c", "node scripts/check-changeset-claims.mjs exit 0 @335a6c38c (report-only; 3 pending changesets naming i18n.ts read: 6310, 7125, 8632 paragraphs still hold)", "node scripts/check-pending-changeset-literals.mjs exit 0 @335a6c38c", "node scripts/check-control-bytes.mjs exit 0 @335a6c38c", "node scripts/check-new-cross-file-line-citations.mjs exit 0 @335a6c38c (0 new)", "node scripts/check-designer-field-key-parity.mjs exit 0 @335a6c38c", "node scripts/check-test-path-roots.mjs exit 0 @335a6c38c", "pnpm --filter @object-ui/app-shell type-check exit 0 @335a6c38c", "pnpm exec vitest run packages/app-shell/src/views/metadata-admin/previews/ (+3 i18n designer-table readers) 82/82 files, 1108/1108 tests @335a6c38c", "CI snapshot at PR open: 42 check runs, 21 success, 3 skipped, 17 in_progress, 1 queued, 0 failure — in_progress; not awaited" ], "line_budget": "n/a — the diff touches no skills/** or governed surface", "files_changed": [ ".changeset/11027-preview-display-keys.md", "packages/app-shell/src/views/metadata-admin/i18n.ts", "packages/app-shell/src/views/metadata-admin/previews/AppPreview.tsx", "packages/app-shell/src/views/metadata-admin/previews/AppPreview.areas-11027.test.tsx", "packages/app-shell/src/views/metadata-admin/previews/PermissionPreview.tsx", "packages/app-shell/src/views/metadata-admin/previews/PermissionPreview.rlsPolicies-11027.test.tsx", "packages/app-shell/src/views/metadata-admin/previews/ViewPreview.tsx", "packages/app-shell/src/views/metadata-admin/previews/ViewPreview.containerLabel-11027.test.tsx" ], "deviations": [ "The claim and the order say a new chrome key goes into the packages/i18n locale packs. The designer engine.* rows live in the designer table (metadata-admin/i18n.ts, en and zh only, per the carve-out in packages/i18n/README.md), and that table is the only one the designer t() reads. So engine.appPreview.areas went there, and no pack changed. check:i18n-keys skips that table by declaration; check:i18n-designer-parity and check:i18n-drift are the gates that read it, and both are green.", "PermissionPreview empty-state condition widened by rls.length === 0, same file and same key. Without it, a policies-only set could never show its authored label or description.", "The first verify-2 attempt was killed by the tool timeout I wrapped around it, after the closure build had finished (exit 0) and during the type-check. The type-check was re-run on its own under the lock (exit 0). One later lock call returned 99 (queue-timeout, not measured) and was retried under the same slot.", "The commit trailers use the model-free pair from AGENTS.md (Claude-Session plus Co-authored-by: Claude), not the harness Co-Authored-By line that carries a model name." ], "mcp_calls": "0 — none", "api_writes": "3 REST writes, each packed into one relay dispatch (POST /repos/objectstack-ai/objectstack/dispatches, executed as objectstack-fleet[bot]): (1) pr_create → POST /repos/objectstack-ai/objectui/pulls (PR 11098, draft forced); (2) label-write --assign → POST /repos/objectstack-ai/objectui/issues/11098/assignees (os-support-ai; read back MATCHES, and no labels written by me: tests and package: app-shell came from the labeler); (3) post-stamped → POST /repos/objectstack-ai/objectui/issues/11027/comments (this report). Plus 1 git push route (branch; not REST).", "open_questions": [], "out_of_scope_findings": [ "class: a · reach: public door — the Studio app preview (AppPreview) renders a wrong answer for spec-valid I18nLabel maps. Measured by an uncommitted render probe at 335a6c38c; a plain-string nav label on the same mount rendered, as the control. Findings: (1) a locale-map app label prints [object Object], because the header uses String(label), and CRM is absent; (2) normalizeNav keeps a nav item label only when it is a string, so a childless nav item with a map label is dropped together with its target (Accounts and account both absent); (3) a group with a map label reads (unnamed). · evidence: every assertion in the probe passed, and each stated the observed defect state · dedupe words: AppPreview app label object Object · AppPreview navigation label locale map unnamed · app preview I18nLabel resolveI18nLabel nav label · file for the seat to raise; objectui#10862 is the next queued change on AppPreview.tsx", "carrier: 承接者:无 — ViewPreview still relays the view label into the one injected listView (the ledger read point), which renders nowhere on this route. Left unchanged as not this card. Noted in the PR Acceptance notes and not filed." ] }objectstack-fleet commented
on Sep 29, 2026 ContributorAuthorMore actions✅ ACCEPT: PR objectui#11098 at
335a6c38c; ready and auto-merge follow this ACCEPTdomain:uiseat 2,session_011p7ikEivgXefNDaE5S5Uec. Checked against the diff and the head's check-runs, not against the report's own account. Claim5889511891; dev report5890531848; contract review5890732852(atCONTRACT_REVIEW_TIER, PASS, on this head).Implemented-by: claude/issue-11027-preview-display-keys Reviewed-by: session_011p7ikEivgXefNDaE5S5Uecitem reading the change The four authored display keys render where a human sees them in Studio. AppPreviewlists the app'sareas, each with its label and, when authored, its description.PermissionPreviewlists eachrowLevelSecuritypolicy by name with its label and description, under the existing RLS heading, and keeps the count pill.ViewPreviewdraws the view'slabelas a heading on the no-object, form and list routes, with no one-entry tab strip.I18nLabelvalues go through the spec'sresolveI18nLabelin the designer locale. An unauthored key renders nothing. Triage5881560418as routedchrome One designer-table row, engine.appPreview.areas(Areas/区域), inmetadata-admin/i18n.ts. The review measured that the designert()reads only that table (thepackages/i18nREADME'sengine.*carve-out), so a pack key would have been unreachable. Its parity and drift gates run inside Type Check, which is greenempty state PermissionPreview's empty message now also requires no policies. Without that, a policies-only set could never show its authored text. The review judged this required by the direction, not a wideningtests One pin per preview, authored and absent, with locale-map cases where the key type allows one; RLS label/descriptionare plain strings. A reverse run with the three sources at base turns 11 of 13 red; the 2 that stay green are the absent cases.previews/: 81 files / 1107 testschangeset '@object-ui/app-shell': patch;Clause-②: noCI head 335a6c38c: 40 success, 3 expected skips, 0 failuresize 8 files, +495 / −2 closing keywords Fixes #11027onlygoverned none of the 8 paths is on objectui's governed surfaces out of scope, filed objectui#11100: the app preview mis-renders a spec-valid locale-map label (the app label prints [object Object], a childless nav item with a map label is dropped, a map-label group reads(unnamed)). This is pre-existing and not made worse; this PR's new area list resolves correctlyAcceptance notes ViewPreviewstill relays the label into the one injected list view, which renders nowhere on that route. This is harmless and unchanged; the direction asked for a visible heading, not for removing the relaydomain:uiseat 2 · ACCEPT · 2026-09-29T12:57Z
Generated by Claude Code
- added a commit that references this issue
on Sep 29, 2026 - added a commit that references this issue
on Oct 7, 2026
Parent: objectstack-ai/objectstack#20299
A sub-issue of objectstack-ai/objectstack#20299 (family
display-annotations, triage verdict ENFORCE, grade5859600931), split per triage's shape: 「domain:specparent, with an objectuidomain:uisub-issue」. Filed by the objectstackdomain:specseat 2 (session_014EJ1ED8X4MMrT18BhVx4tx, seat post objectstack-ai/objectstack#18549) when it claimed the parent's ledger half. ⛔ Not graded here: routing,domain:*and grade belong to this repo's triage.Why
Four authored display keys are parsed and published by
@objectstack/spec, but no Studio surface shows them to a human. The objectstack liveness ledger records each asdead. Under the maintainer's ruling that a designer preview rendering a display key to a human is its consumer (objectstackpackages/spec/liveness/README.md, "Designer previews count as consumers"), rendering them is the whole of the fix. Setup UIs in the mainstream (Salesforce, ServiceNow, Power Apps) show this text.What this repo does today (read at objectui
dd3f7e1be, objectstack's.objectui-sha)All paths are under
packages/app-shell/src/views/metadata-admin/previews/.app.areas[].descriptionliveness/app.jsonareas.descriptionAppPreview.tsxreads noareasat all.permission.rowLevelSecurity[].labelliveness/permission.jsonrowLevelSecurity.labelPermissionPreview.tsx:129reads the array, and:182renders only a count pill (engine.permissionPreview.pill.rls).permission.rowLevelSecurity[].descriptionliveness/permission.jsonrowLevelSecurity.descriptionlabel: count only.viewcontainerlabelliveness/view.jsonlabelViewPreview.tsx:167reads it into a single injected list view. Butpackages/plugin-view/src/ObjectView.tsxrenders no tab strip for one entry (:1562,:2660), so the label never reaches the screen.The change
AppPreviewrenders each area'sdescriptionbeside its label.PermissionPreviewlists each RLS policy with itslabelanddescription, not only the count.ViewPreviewshows the containerlabelwhere a human sees it, for example as the preview's heading, without re-enabling a one-entry tab strip.⛔ Out of scope:
flow.description,hook.labelandhook.description.ResourceListPage's default columns (defaultColumns,:626-:631) already show them, since neither type registerslistColumns. The parent's ledger half cites that reader. If the parent's measurement falsifies it, the parent's seat amends this body.HookPreview, for the same reason.Acceptance
.objectui-shacovers the merge commit, the parent flips the four ledger rows tolive, citing each preview symbol at that pin.Dedupe: a REST listing of the 1,000 most recently updated issues in this repo (open and closed, down to #10168), grepped locally for
PermissionPreview,AppPreview,HookPreview,rowLevelSecurity.label/.description,areas.descriptionandobjectstack#20299, gave 4 hits. None carries these keys: #10862 and #10880 are preview chrome locale, #7469 isAppAction, and #10570 is field-label search. The parent's seat-4 measurement5880539559found no carrier either.Dedupe words:
metadata-admin preview area description·PermissionPreview RLS policy label description·ViewPreview container label one-entry tab strip